1 /*
2 * Copyright (c) 2017 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief gPTP message helpers.
10 *
11 * This is not to be included by the application.
12 */
13
14 #ifndef __GPTP_MESSAGES_H
15 #define __GPTP_MESSAGES_H
16
17 #include <zephyr/net/net_pkt.h>
18 #include <zephyr/net/ethernet.h>
19 #include <zephyr/net/gptp.h>
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 /* Helpers to access gPTP messages. */
26 #define GPTP_HDR(pkt) gptp_get_hdr(pkt)
27 #define GPTP_ANNOUNCE(pkt) ((struct gptp_announce *)gptp_data(pkt))
28 #define GPTP_SIGNALING(pkt) ((struct gptp_signaling *)gptp_data(pkt))
29 #define GPTP_SYNC(pkt) ((struct gptp_sync *)gptp_data(pkt))
30 #define GPTP_FOLLOW_UP(pkt) ((struct gptp_follow_up *)gptp_data(pkt))
31 #define GPTP_DELAY_REQ(pkt) \
32 ((struct gptp_delay_req *)gptp_data(pkt))
33 #define GPTP_PDELAY_REQ(pkt) \
34 ((struct gptp_pdelay_req *)gptp_data(pkt))
35 #define GPTP_PDELAY_RESP(pkt) \
36 ((struct gptp_pdelay_resp *)gptp_data(pkt))
37 #define GPTP_PDELAY_RESP_FOLLOWUP(pkt) \
38 ((struct gptp_pdelay_resp_follow_up *)gptp_data(pkt))
39
40 /* Field values. */
41 #define GPTP_TRANSPORT_802_1_AS 0x1
42 #define GPTP_VERSION 0x2
43
44 /* Message Lengths. */
45 #define GPTP_PACKET_LEN(pkt) net_pkt_get_len(pkt)
46 #define GPTP_VALID_LEN(pkt, len) \
47 (len > (NET_ETH_MINIMAL_FRAME_SIZE - GPTP_L2_HDR_LEN(pkt)))
48 #define GPTP_L2_HDR_LEN(pkt) \
49 ((long)GPTP_HDR(pkt) - (long)NET_ETH_HDR(pkt))
50
51 #define GPTP_SYNC_LEN \
52 (sizeof(struct gptp_hdr) + sizeof(struct gptp_sync))
53 #define GPTP_FOLLOW_UP_LEN \
54 (sizeof(struct gptp_hdr) + sizeof(struct gptp_follow_up))
55 #define GPTP_PDELAY_REQ_LEN \
56 (sizeof(struct gptp_hdr) + sizeof(struct gptp_pdelay_req))
57 #define GPTP_PDELAY_RESP_LEN \
58 (sizeof(struct gptp_hdr) + sizeof(struct gptp_pdelay_resp))
59 #define GPTP_PDELAY_RESP_FUP_LEN \
60 (sizeof(struct gptp_hdr) + sizeof(struct gptp_pdelay_resp_follow_up))
61 #define GPTP_SIGNALING_LEN \
62 (sizeof(struct gptp_hdr) + sizeof(struct gptp_signaling))
63
64 /* For the Announce message, the TLV is variable length. The len field
65 * indicates the length of the TLV not accounting for tlvType and lengthField
66 * which are 4 bytes.
67 */
68 #define GPTP_ANNOUNCE_LEN(pkt) \
69 (sizeof(struct gptp_hdr) + sizeof(struct gptp_announce) \
70 + ntohs(GPTP_ANNOUNCE(pkt)->tlv.len) \
71 - sizeof(struct gptp_path_trace_tlv) + 4)
72
73 #define GPTP_CHECK_LEN(pkt, len) \
74 ((GPTP_PACKET_LEN(pkt) != len) && (GPTP_VALID_LEN(pkt, len)))
75 #define GPTP_ANNOUNCE_CHECK_LEN(pkt) \
76 ((GPTP_PACKET_LEN(pkt) != GPTP_ANNOUNCE_LEN(pkt)) && \
77 (GPTP_VALID_LEN(pkt, GPTP_ANNOUNCE_LEN(pkt))))
78
79 /* Header Flags. Byte 0. */
80 #define GPTP_FLAG_ALT_MASTER BIT(0)
81 #define GPTP_FLAG_TWO_STEP BIT(1)
82 #define GPTP_FLAG_UNICAST BIT(2)
83 #define GPTP_FLAG_PROFILE_SPECIFIC1 BIT(5)
84 #define GPTP_FLAG_PROFILE_SPECIFIC2 BIT(6)
85
86 /* Header Flags. Byte 1. */
87 #define GPTP_FLAG_LEAP61 BIT(0)
88 #define GPTP_FLAG_LEAP59 BIT(1)
89 #define GPTP_FLAG_CUR_UTC_OFF_VALID BIT(2)
90 #define GPTP_FLAG_PTP_TIMESCALE BIT(3)
91 #define GPTP_FLAG_TIME_TRACEABLE BIT(4)
92 #define GPTP_FLAG_FREQ_TRACEABLE BIT(5)
93
94 /* Signaling Interval Flags. */
95 #define GPTP_FLAG_COMPUTE_NEIGHBOR_RATE_RATIO 0x1
96 #define GPTP_FLAG_COMPUTE_NEIGHBOR_PROP_DELAY 0x2
97
98 /* Signaling Interval Values. */
99 #define GPTP_ITV_KEEP -128
100 #define GPTP_ITV_SET_TO_INIT 126
101 #define GPTP_ITV_STOP 127
102
103 /* Control. Only set for header compatibility with v1. */
104 #define GPTP_SYNC_CONTROL_VALUE 0x0
105 #define GPTP_FUP_CONTROL_VALUE 0x2
106 #define GPTP_OTHER_CONTROL_VALUE 0x5
107
108 /* Other default values. */
109 #define GPTP_RESP_LOG_MSG_ITV 0x7F
110 #define GPTP_ANNOUNCE_MSG_PATH_SEQ_TYPE htons(0x8)
111
112 /* Organization Id used for TLV. */
113 #define GPTP_FUP_TLV_ORG_ID_BYTE_0 0x00
114 #define GPTP_FUP_TLV_ORG_ID_BYTE_1 0x80
115 #define GPTP_FUP_TLV_ORG_ID_BYTE_2 0xC2
116 #define GPTP_FUP_TLV_ORG_SUB_TYPE 0x01
117
118 /* Organizationally Unique Identifiers */
119 #define OUI_IEEE_802_1_COMMITTEE 0x00, 0x80, 0xC2
120
121 /**
122 * @brief gPTP Clock Quality
123 *
124 * Defines the quality of a clock.
125 * This is used by the Best Master Clock Algorithm.
126 */
127 struct gptp_clock_quality {
128 uint8_t clock_class;
129 uint8_t clock_accuracy;
130 uint16_t offset_scaled_log_var;
131 } __packed;
132
133 /**
134 * @brief gPTP Root System Identity
135 *
136 * Defines the Grand Master of a clock.
137 * This is used by the Best Master Clock Algorithm.
138 */
139 struct gptp_root_system_identity {
140 /** Grand Master priority1 component. */
141 uint8_t grand_master_prio1;
142
143 /** Grand Master clock quality. */
144 struct gptp_clock_quality clk_quality;
145
146 /** Grand Master priority2 component. */
147 uint8_t grand_master_prio2;
148
149 /** Grand Master clock identity. */
150 uint8_t grand_master_id[GPTP_CLOCK_ID_LEN];
151 } __packed;
152
153 /* Definition of all message types as defined by IEEE802.1AS. */
154
155 struct gptp_path_trace_tlv {
156 /** TLV type: 0x8. */
157 uint16_t type;
158
159 /** Length. Number of TLVs * 8 bytes. */
160 uint16_t len;
161
162 /** ClockIdentity array of the successive time-aware systems. */
163 uint8_t path_sequence[1][8];
164 } __packed;
165
166 struct gptp_announce {
167 /** Reserved fields. */
168 uint8_t reserved1[10];
169
170 /** Current UTC offset. */
171 int16_t cur_utc_offset;
172
173 /** Reserved field. */
174 uint8_t reserved2;
175
176 /* gmPriorityVector priority 1 of the peer sending the message. */
177 struct gptp_root_system_identity root_system_id;
178
179 /** masterStepsRemoved of the peer sending the message. */
180 uint16_t steps_removed;
181
182 /** timeSource of the peer sending the message. */
183 uint8_t time_source;
184
185 /* Path Trace TLV. This field has a variable length. */
186 struct gptp_path_trace_tlv tlv;
187 } __packed;
188
189 struct gptp_sync {
190 /** Reserved field. This field is used for PTPv2, unused in gPTP. */
191 uint8_t reserved[10];
192 } __packed;
193
194 struct gptp_follow_up_tlv_hdr {
195 /** TLV type: 0x3. */
196 uint16_t type;
197
198 /** Length: 28. */
199 uint16_t len;
200 } __packed;
201
202 struct gptp_follow_up_tlv {
203 /** Organization Id: 00-80-C2. */
204 uint8_t org_id[3];
205
206 /** Organization Sub Type: 1. */
207 uint8_t org_sub_type[3];
208
209 /** Rate ratio relative to the grand master of the peer. */
210 int32_t cumulative_scaled_rate_offset;
211
212 /** Time Base Indicator of the current Grand Master. */
213 uint16_t gm_time_base_indicator;
214
215 /** Difference of the time between the current GM and the previous. */
216 struct gptp_scaled_ns last_gm_phase_change;
217
218 /** Diff of the frequency between the current GM and the previous. */
219 int32_t scaled_last_gm_freq_change;
220 } __packed;
221
222 struct gptp_follow_up {
223 /** Higher 16 bits of the seconds at which the sync was sent. */
224 uint16_t prec_orig_ts_secs_high;
225
226 /** Lower 32 bits of the seconds at which the sync was sent. */
227 uint32_t prec_orig_ts_secs_low;
228
229 /** Nanoseconds at which the sync was sent. */
230 uint32_t prec_orig_ts_nsecs;
231
232 /** Follow up TLV. */
233 struct gptp_follow_up_tlv_hdr tlv_hdr;
234 struct gptp_follow_up_tlv tlv;
235 } __packed;
236
237 struct gptp_pdelay_req {
238 /** Reserved fields. */
239 uint8_t reserved1[10];
240
241 /** Reserved fields. */
242 uint8_t reserved2[10];
243 } __packed;
244
245 struct gptp_pdelay_resp {
246 /** Higher 16 bits of the seconds at which the request was received. */
247 uint16_t req_receipt_ts_secs_high;
248
249 /** Lower 32 bits of the seconds at which the request was received. */
250 uint32_t req_receipt_ts_secs_low;
251
252 /** Nanoseconds at which the pdelay request was received. */
253 uint32_t req_receipt_ts_nsecs;
254
255 /** Source Port Id of the Path Delay Request. */
256 struct gptp_port_identity requesting_port_id;
257 } __packed;
258
259 struct gptp_pdelay_resp_follow_up {
260 /** Higher 16 bits of the seconds at which the response was sent. */
261 uint16_t resp_orig_ts_secs_high;
262
263 /** Lower 32 bits of the seconds at which the response was sent. */
264 uint32_t resp_orig_ts_secs_low;
265
266 /** Nanoseconds at which the response was received. */
267 uint32_t resp_orig_ts_nsecs;
268
269 /** Source Port Id of the Path Delay Request. */
270 struct gptp_port_identity requesting_port_id;
271 } __packed;
272
273 struct gptp_message_itv_req_tlv {
274 /** TLV type: 0x3. */
275 uint16_t type;
276
277 /** Length field: 12. */
278 uint16_t len;
279
280 /** Organization Id: 00-80-C2. */
281 uint8_t org_id[3];
282
283 /** Organization sub type: 0x2. */
284 uint8_t org_sub_type[3];
285
286 /** Log to base 2 of the mean time interval between pdelay requests. */
287 int8_t link_delay_itv;
288
289 /** Log to base 2 of the mean time interval between syncs. */
290 int8_t time_sync_itv;
291
292 /** Log to base 2 of the mean time interval between announces. */
293 int8_t announce_itv;
294
295 /** Flags (computeNeighborRateRatio and computeNeighborPropDelay). */
296 union {
297 struct {
298 uint8_t compute_neighbor_rate_ratio : 1;
299 uint8_t compute_neighbor_prop_delay : 1;
300 };
301 uint8_t flags;
302 };
303 /** Reserved fields. */
304 uint8_t reserved[2];
305 } __packed;
306
307 struct gptp_signaling {
308 /** Target Port Identity , always 0xFF. */
309 struct gptp_port_identity target_port_id;
310
311 /** Message Interval TLV. */
312 struct gptp_message_itv_req_tlv tlv;
313 } __packed;
314
315 /**
316 * @brief Compute gPTP message location.
317 *
318 * @param pkt Network Buffer containing a gPTP message.
319 *
320 * @return Pointer to the start of the gPTP message inside the packet.
321 */
gptp_data(struct net_pkt * pkt)322 static inline uint8_t *gptp_data(struct net_pkt *pkt)
323 {
324 return (uint8_t *)GPTP_HDR(pkt) + sizeof(struct gptp_hdr);
325 }
326
327 /* Functions to prepare messages. */
328
329 /**
330 * @brief Prepare Sync message.
331 *
332 * @param port gPTP port number.
333 *
334 * @return Pointer to the prepared Network Buffer.
335 */
336 struct net_pkt *gptp_prepare_sync(int port);
337
338 /**
339 * @brief Prepare Follow Up message.
340 *
341 * @param port gPTP port number.
342 *
343 * @return Pointer to the prepared Network Buffer.
344 */
345 struct net_pkt *gptp_prepare_follow_up(int port, struct net_pkt *sync);
346
347 /**
348 * @brief Prepare Path Delay Request message.
349 *
350 * @param port gPTP port number.
351 *
352 * @return Pointer to the prepared Network Buffer.
353 */
354 struct net_pkt *gptp_prepare_pdelay_req(int port);
355
356 /**
357 * @brief Prepare Path Delay Response message.
358 *
359 * @param port gPTP port number.
360 * @param req Path Delay Request to reply to.
361 *
362 * @return Pointer to the prepared Network Buffer.
363 */
364 struct net_pkt *gptp_prepare_pdelay_resp(int port,
365 struct net_pkt *req);
366
367 /**
368 * @brief Prepare Announce message.
369 *
370 * @param port gPTP port number.
371 *
372 * @return Pointer to the prepared Network Buffer.
373 */
374 struct net_pkt *gptp_prepare_announce(int port);
375
376 /**
377 * @brief Prepare Path Delay Response message.
378 *
379 * @param port gPTP port number.
380 * @param resp Related Path Delay Follow Up.
381 *
382 * @return Pointer to the prepared Network Buffer.
383 */
384 struct net_pkt *gptp_prepare_pdelay_follow_up(int port,
385 struct net_pkt *resp);
386
387 /* Functions to handle received messages. */
388
389 /**
390 * @brief Handle Sync message.
391 *
392 * @param port gPTP port number.
393 * @param pkt Network Buffer.
394 */
395 void gptp_handle_sync(int port, struct net_pkt *pkt);
396
397 /**
398 * @brief Handle Follow Up message.
399 *
400 * @param port gPTP port number.
401 * @param pkt Network Buffer to parse.
402 *
403 * @return 0 if success, Error Code otherwise.
404 */
405 int gptp_handle_follow_up(int port, struct net_pkt *pkt);
406
407 /**
408 * @brief Handle Path Delay Request message.
409 *
410 * @param port gPTP port number.
411 * @param pkt Network Buffer.
412 */
413 void gptp_handle_pdelay_req(int port, struct net_pkt *pkt);
414
415 /**
416 * @brief Handle Path Delay Response message.
417 *
418 * @param port gPTP port number.
419 * @param pkt Network Buffer to parse.
420 *
421 * @return 0 if success, Error Code otherwise.
422 */
423 int gptp_handle_pdelay_resp(int port, struct net_pkt *pkt);
424
425 /**
426 * @brief Handle Path Delay Follow Up message.
427 *
428 * @param port gPTP port number.
429 * @param pkt Network Buffer to parse.
430 *
431 * @return 0 if success, Error Code otherwise.
432 */
433 int gptp_handle_pdelay_follow_up(int port, struct net_pkt *pkt);
434
435 /**
436 * @brief Handle Signaling message.
437 *
438 * @param port gPTP port number.
439 * @param pkt Network Buffer
440 */
441 void gptp_handle_signaling(int port, struct net_pkt *pkt);
442
443 /* Functions to send messages. */
444
445 /**
446 * @brief Send a Sync message.
447 *
448 * @param port gPTP port number.
449 * @param pkt Sync message.
450 */
451 void gptp_send_sync(int port, struct net_pkt *pkt);
452
453 /**
454 * @brief Send a Follow Up message.
455 *
456 * @param port gPTP port number.
457 * @param pkt Follow Up message.
458 */
459 void gptp_send_follow_up(int port, struct net_pkt *pkt);
460
461 /**
462 * @brief Send an Announce message.
463 *
464 * @param port gPTP port number.
465 * @param pkt Announce message.
466 */
467 void gptp_send_announce(int port, struct net_pkt *pkt);
468
469 /**
470 * @brief Send a Path Delay Request on the given port.
471 *
472 * @param port gPTP port number.
473 */
474 void gptp_send_pdelay_req(int port);
475
476 /**
477 * @brief Send a Path Delay Response for the given Path Delay Request.
478 *
479 * @param port gPTP port number.
480 * @param pkt Network Buffer containing the prepared Path Delay Response.
481 * @param treq Time at which the Path Delay Request was received.
482 */
483 void gptp_send_pdelay_resp(int port, struct net_pkt *pkt,
484 struct net_ptp_time *treq);
485
486 /**
487 * @brief Send a Path Delay Response for the given Path Delay Request.
488 *
489 * @param port gPTP port number.
490 * @param pkt Network Buffer containing the prepared Path Delay Follow Up.
491 * @param tresp Time at which the Path Delay Response was sent.
492 */
493 void gptp_send_pdelay_follow_up(int port, struct net_pkt *pkt,
494 struct net_ptp_time *tresp);
495
496 #ifdef __cplusplus
497 }
498 #endif
499
500 #endif /* __GPTP_MESSAGES_H */
501