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