From b348d9886b6bd05c6c88c461bc01639f865bf89f Mon Sep 17 00:00:00 2001 From: Scramble Tools <162384439+scrambletools@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:40:34 -0800 Subject: [PATCH] feat(ethernet/ptp): support for responding to peer delay req respond to peer delay req, and minor cleanup for consistency/readability; tested with Motu AVB switch and receiving syncs from switch which indicates that AVB is happy with peer delay --- components/hal/emac_hal.c | 2 + .../ptp/components/ptpd/include/ptpd.h | 3 +- examples/ethernet/ptp/components/ptpd/ptpd.c | 230 ++++++++++++++++-- examples/ethernet/ptp/components/ptpd/ptpv2.h | 41 ++-- 4 files changed, 227 insertions(+), 49 deletions(-) diff --git a/components/hal/emac_hal.c b/components/hal/emac_hal.c index a8ee895ffc72..60ce490a8f38 100644 --- a/components/hal/emac_hal.c +++ b/components/hal/emac_hal.c @@ -258,6 +258,8 @@ esp_err_t emac_hal_ptp_start(emac_hal_context_t *hal, const emac_hal_ptp_config_ { uint8_t base_increment; + emac_ll_ts_ptp_snap_type_sel(hal->ptp_regs, 1); + // Enable time stamping frame filtering (applicable to receive) emac_ll_ts_ptp_ether_enable(hal->ptp_regs, true); // Process frames with v2 format diff --git a/examples/ethernet/ptp/components/ptpd/include/ptpd.h b/examples/ethernet/ptp/components/ptpd/include/ptpd.h index 0a65c4885b30..166cecc2c6af 100644 --- a/examples/ethernet/ptp/components/ptpd/include/ptpd.h +++ b/examples/ethernet/ptp/components/ptpd/include/ptpd.h @@ -89,9 +89,10 @@ struct ptpd_status_s long drift_ppb; - /* Averaged path delay */ + /* Averaged delay */ long path_delay_ns; + long peer_delay_ns; /* Timestamps of latest received packets (CLOCK_MONOTONIC) */ diff --git a/examples/ethernet/ptp/components/ptpd/ptpd.c b/examples/ethernet/ptp/components/ptpd/ptpd.c index 708ec0c18d9f..2a58a40a7075 100644 --- a/examples/ethernet/ptp/components/ptpd/ptpd.c +++ b/examples/ethernet/ptp/components/ptpd/ptpd.c @@ -112,6 +112,15 @@ #ifndef CONFIG_NETUTILS_PTPD_PATH_DELAY_STABILITY_NS #define CONFIG_NETUTILS_PTPD_PATH_DELAY_STABILITY_NS 0 #endif +#ifndef CONFIG_NETUTILS_PTPD_PEER_DELAY_STABILITY_NS +#define CONFIG_NETUTILS_PTPD_PEER_DELAY_STABILITY_NS 0 +#endif +#ifndef CONFIG_NETUTILS_PTPD_GPTP_PROFILE +#define CONFIG_NETUTILS_PTPD_GPTP_PROFILE 1 +#endif +#ifndef CONFIG_NETUTILS_PTPD_MAX_PEER_DELAY_NS +#define CONFIG_NETUTILS_PTPD_MAX_PEER_DELAY_NS 100000LL // 100us +#endif #define clock_timespec_subtract(ts1, ts2, ts3) timespecsub(ts1, ts2, ts3) #define clock_timespec_add(ts1, ts2, ts3) timespecadd(ts1, ts2, ts3) @@ -169,6 +178,7 @@ struct ptp_state_s int64_t local_time_ns_prev; int64_t last_offset_ns; + double correction; // from last offset message pi_cntrl_t offset_pi; #else @@ -230,9 +240,11 @@ struct ptp_state_s /* Timestamps related to path delay calculation (CLOCK_REALTIME) */ bool can_send_delayreq; - struct timespec delayreq_time; + struct timespec delayreq_time; // time of last delay_req sent int path_delay_avgcount; + int peer_delay_avgcount; long path_delay_ns; + long peer_delay_ns; // used for gPTP peer delay measurement long delayreq_interval; /* Latest received packet and its timestamp (CLOCK_REALTIME) */ @@ -250,6 +262,14 @@ struct ptp_state_s struct ptp_sync_s twostep_packet; struct timespec twostep_rxtime; + + /* Buffered delay_resp packet for two-step peer delay measurement where server sends + * the accurate response origin timestamp in a separate follow-up message. + */ + + struct ptp_delay_resp_s twostep_delay_resp_packet; + struct timespec twostep_delay_resp_rxtime; + }; #ifdef CONFIG_NETUTILS_PTPD_SERVER @@ -288,6 +308,29 @@ static struct ptp_state_s *s_state; * Private Functions ****************************************************************************/ #ifdef ESP_PTP + +static int64_t get_correction_ns(uint8_t *correction_field) +{ + // Convert 6 bytes to 64-bit signed integer (nanoseconds << 16) + int64_t correction = 0; + + // Handle sign extension for negative numbers + if (correction_field[0] & 0x80) { + correction = -1LL; // Fill with 1's for negative number + } + + // Build the value byte by byte + correction = (correction << 8) | correction_field[0]; + correction = (correction << 8) | correction_field[1]; + correction = (correction << 8) | correction_field[2]; + correction = (correction << 8) | correction_field[3]; + correction = (correction << 8) | correction_field[4]; + correction = (correction << 8) | correction_field[5]; + + // Convert from 2^16 scale to nanoseconds + return correction >> 16; +} + static void ptp_create_eth_frame(struct ptp_state_s *state, uint8_t *eth_frame, void *ptp_msg, uint16_t ptp_msg_len) { struct eth_hdr eth_hdr = { @@ -955,10 +998,11 @@ static int ptp_send_announce(FAR struct ptp_state_s *state) memset(&msg, 0, sizeof(msg)); msg = state->own_identity; msg.header.messagetype = PTP_MSGTYPE_ANNOUNCE; - msg.header.messagelength[1] = sizeof(msg); + msg.header.messagelength[1] = sizeof(struct ptp_announce_s); #ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE - msg.header.flags[1] = PTP_FLAGS1_PTP_TIMESCALE; + msg.header.messagetype |= PTP_MSGTYPE_SDOID_GPTP; // gPTP profile message + msg.header.flags[1] = PTP_FLAGS1_PTP_TIMESCALE; // gPTP required flag #endif ptp_increment_sequence(&state->announce_seq, &msg.header); @@ -1028,7 +1072,8 @@ static int ptp_send_sync(FAR struct ptp_state_s *state) msg.header.flags[0] = PTP_FLAGS0_TWOSTEP; #endif #ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE - msg.header.flags[1] = PTP_FLAGS1_PTP_TIMESCALE; + msg.header.messagetype |= PTP_MSGTYPE_SDOID_GPTP; // gPTP profile message + msg.header.flags[1] = PTP_FLAGS1_PTP_TIMESCALE; // gPTP required flag #endif #ifndef ESP_PTP @@ -1073,6 +1118,9 @@ static int ptp_send_sync(FAR struct ptp_state_s *state) msg.header.messagelength[1] = sizeof(struct ptp_follow_up_s); msg.header.flags[0] = 0; // Reset 2-step flag msg.header.controlfield = 2; // Follow-up message + + /* Add the information TLV (required for gPTP and ignored otherwise) */ + struct ptp_info_tlv_s info_tlv; memset(&info_tlv, 0, sizeof(info_tlv)); info_tlv.type[1] = 3; // Organization extension @@ -1114,7 +1162,7 @@ static int ptp_send_sync(FAR struct ptp_state_s *state) static int ptp_send_delay_req(FAR struct ptp_state_s *state) { - struct ptp_delay_req_s req; + struct ptp_delay_req_s msg; #ifndef ESP_PTP struct sockaddr_in addr; #endif // !ESP_PTP @@ -1126,19 +1174,30 @@ static int ptp_send_delay_req(FAR struct ptp_state_s *state) addr.sin_port = HTONS(PTP_UDP_PORT_EVENT); #endif // !ESP_PTP - memset(&req, 0, sizeof(req)); - req.header = state->own_identity.header; - req.header.messagetype = PTP_MSGTYPE_DELAY_REQ; - req.header.messagelength[1] = sizeof(req); - ptp_increment_sequence(&state->delay_req_seq, &req.header); + memset(&msg, 0, sizeof(msg)); + msg.header = state->own_identity.header; +#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + msg.header.messagetype = PTP_MSGTYPE_PDELAY_REQ; +#else + msg.header.messagetype = PTP_MSGTYPE_DELAY_REQ; +#endif + msg.header.messagelength[1] = sizeof(struct ptp_delay_req_s); + +#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + msg.header.messagetype |= PTP_MSGTYPE_SDOID_GPTP; // gPTP profile message + msg.header.flags[1] = PTP_FLAGS1_PTP_TIMESCALE; // gPTP required flag + msg.header.controlfield = 5; +#endif + + ptp_increment_sequence(&state->delay_req_seq, &msg.header); ptp_gettime(state, &state->delayreq_time); - timespec_to_ptp_format(&state->delayreq_time, req.origintimestamp); + timespec_to_ptp_format(&state->delayreq_time, msg.origintimestamp); #ifdef ESP_PTP - ret = ptp_net_send(state, &req, sizeof(req), &state->delayreq_time); + ret = ptp_net_send(state, &msg, sizeof(struct ptp_delay_req_s), &state->delayreq_time); #else - ret = sendto(state->tx_socket, &req, sizeof(req), 0, + ret = sendto(state->tx_socket, &msg, sizeof(struct ptp_delay_req_s), 0, (FAR struct sockaddr *)&addr, sizeof(addr)); #endif // ESP_PTP @@ -1158,7 +1217,7 @@ static int ptp_send_delay_req(FAR struct ptp_state_s *state) { clock_gettime(CLOCK_MONOTONIC, &state->last_transmitted_delayreq); ptpinfo("Sent delay req, seq %ld\n", - (long)ptp_get_sequence(&req.header)); + (long)ptp_get_sequence(&msg.header)); } return ret; @@ -1236,6 +1295,8 @@ static int ptp_process_announce(FAR struct ptp_state_s *state, state->last_received_sync = state->last_received_announce; state->path_delay_avgcount = 0; state->path_delay_ns = 0; + state->peer_delay_avgcount = 0; + state->peer_delay_ns = 0; state->delayreq_time.tv_sec = 0; } } @@ -1250,7 +1311,11 @@ static void ptp_lock_local_clock_freq(FAR struct ptp_state_s *state, { // Compute how off we are against master int64_t offset_ns = timespec_delta_ns(remote_timestamp, local_timestamp); + #if CONFIG_NETUTILS_PTPD_GPTP_PROFILE + offset_ns += state->peer_delay_ns; + #else offset_ns += state->path_delay_ns; + #endif // TODO add offset filter // Execute PI controller to elimitate the offset @@ -1292,7 +1357,11 @@ static void ptp_lock_local_clock_freq(FAR struct ptp_state_s *state, // we would get incorrect delay int64_t diff = llabs(offset_ns) - llabs(state->last_offset_ns); static int cnt = 0; + #if CONFIG_NETUTILS_PTPD_GPTP_PROFILE + if (llabs(diff) < CONFIG_NETUTILS_PTPD_PEER_DELAY_STABILITY_NS) { + #else if (llabs(diff) < CONFIG_NETUTILS_PTPD_PATH_DELAY_STABILITY_NS) { + #endif if (cnt <= 3) cnt++; } else { @@ -1336,7 +1405,11 @@ static int ptp_update_local_clock(FAR struct ptp_state_s *state, (long)remote_timestamp->tv_nsec); delta_ns = timespec_delta_ns(remote_timestamp, local_timestamp); + #ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + delta_ns += state->peer_delay_ns; + #else delta_ns += state->path_delay_ns; + #endif absdelta_ns = (delta_ns < 0) ? -delta_ns : delta_ns; if (absdelta_ns > adj_limit_ns) @@ -1554,8 +1627,15 @@ static int ptp_process_followup(FAR struct ptp_state_s *state, return OK; } + /* Update correction field */ + + double correction_ns; + correction_ns = get_correction_ns(msg->header.correction); + memcpy(&state->correction, &correction_ns, sizeof(correction_ns)); + /* Update local clock based on the remote timestamp we received now * and the local timestamp of when the sync packet was received. + * For gPTP, we can also examine the information TLV for other changes */ ptp_format_to_timespec(msg->origintimestamp, &remote_time); @@ -1589,16 +1669,23 @@ static int ptp_process_delay_req(FAR struct ptp_state_s *state, memset(&msg, 0, sizeof(msg)); msg.header = state->own_identity.header; +#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + msg.header.messagetype = PTP_MSGTYPE_PDELAY_RESP; +#else msg.header.messagetype = PTP_MSGTYPE_DELAY_RESP; +#endif msg.header.messagelength[1] = sizeof(struct ptp_delay_resp_s); #if defined(CONFIG_NETUTILS_PTPD_TWOSTEP_SYNC) || defined(CONFIG_NETUTILS_PTPD_GPTP_PROFILE) msg.header.flags[0] = PTP_FLAGS0_TWOSTEP; #endif + #ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE - msg.header.flags[1] = PTP_FLAGS1_PTP_TIMESCALE; - msg.header.controlfield = 5; // Other message + msg.header.messagetype |= PTP_MSGTYPE_SDOID_GPTP; // gPTP profile message + msg.header.flags[1] = PTP_FLAGS1_PTP_TIMESCALE; // gPTP required flag + msg.header.controlfield = 5; #endif + timespec_to_ptp_format(&state->rxtime, msg.delay_resp.receivetimestamp); memcpy(msg.delay_resp.reqidentity, req->header.sourceidentity, sizeof(req->header.sourceidentity)); @@ -1631,9 +1718,10 @@ static int ptp_process_delay_req(FAR struct ptp_state_s *state, clock_gettime(CLOCK_MONOTONIC, &state->last_transmitted_delayresp); /* gPTP profile requires response follow-up message */ + #ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE timespec_to_ptp_format(&ts, msg.delay_resp_follow_up.origintimestamp); - msg.header.messagetype = PTP_MSGTYPE_DELAY_RESP_FOLLOW_UP; + msg.header.messagetype = PTP_MSGTYPE_PDELAY_RESP_FOLLOW_UP; msg.header.messagelength[1] = sizeof(struct ptp_delay_resp_follow_up_s); msg.header.flags[0] = 0; // Reset 2-step flag @@ -1663,6 +1751,11 @@ static int ptp_process_delay_resp(FAR struct ptp_state_s *state, struct timespec remote_rxtime; uint16_t sequence; +#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + if (memcmp(msg->reqidentity, + state->own_identity.header.sourceidentity, + sizeof(msg->reqidentity)) != 0) +#else if (!state->selected_source_valid || memcmp(msg->header.sourceidentity, state->selected_source.header.sourceidentity, @@ -1670,6 +1763,7 @@ static int ptp_process_delay_resp(FAR struct ptp_state_s *state, memcmp(msg->reqidentity, state->own_identity.header.sourceidentity, sizeof(msg->reqidentity)) != 0) +#endif // CONFIG_NETUTILS_PTPD_GPTP_PROFILE { return OK; /* This packet wasn't for us */ } @@ -1683,11 +1777,18 @@ static int ptp_process_delay_resp(FAR struct ptp_state_s *state, return OK; } +#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + +/* We need to wait for a resp follow-up to calc peer delay. */ + + state->twostep_delay_resp_rxtime = state->rxtime; + state->twostep_delay_resp_packet = *msg; + ptpinfo("Waiting for delay response follow-up\n"); + +#else /* Path delay is calculated as the average between delta for sync * message and delta for delay req message. * (IEEE-1588 section 11.3: Delay request-response mechanism) - * In the case of gPTP (802.1AS), the delay is between peers, not - * between the server and the client. The calculation is still the same. */ ptp_format_to_timespec(msg->receivetimestamp, &remote_rxtime); @@ -1715,9 +1816,6 @@ static int ptp_process_delay_resp(FAR struct ptp_state_s *state, (long long)path_delay); } -#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE - state->delayreq_interval = 0; // gPTP required value -#else /* Calculate interval until next packet */ if (msg->header.logmessageinterval <= 12) { @@ -1735,6 +1833,81 @@ static int ptp_process_delay_resp(FAR struct ptp_state_s *state, return OK; } +static int ptp_process_delay_resp_follow_up(FAR struct ptp_state_s *state, + FAR struct ptp_delay_resp_follow_up_s *msg) +{ + int64_t peer_delay_roundtrip; + int64_t peer_delay_reflection; + int64_t peer_delay; + struct timespec remote_txtime; + struct timespec remote_rxtime; + + if (memcmp(msg->reqidentity, + state->own_identity.header.sourceidentity, + sizeof(msg->reqidentity)) != 0) + + { + return OK; /* This packet wasn't for us */ + } + + if (ptp_get_sequence(&msg->header) + != ptp_get_sequence(&state->twostep_delay_resp_packet.header)) + { + ptpwarn("PTP delay response follow-up packet sequence %ld does not " + "match initial sync packet sequence %ld, ignoring\n", + (long)ptp_get_sequence(&msg->header), + (long)ptp_get_sequence(&state->twostep_delay_resp_packet.header)); + return OK; + } + + /* In gPTP (802.1AS), delay is measured between peers, not + * between the server and the client. It is calculated as follows: + + Peer A Peer B + | | + | Peer delay_req | + t1 |----------------------------------->| t2 + | | + | Peer delay_resp (t2) | + t4 |<-----------------------------------| t3 + | | + | Peer delay_resp_follow_up (t3) | + |<-----------------------------------| + + Peer A calculates peer_delay = ((t4 - t1) - (t3 - t2))/2 + */ + + /* Calculate peer delay */ + + peer_delay_roundtrip = timespec_delta_ns(&state->twostep_delay_resp_rxtime, &state->delayreq_time); + ptp_format_to_timespec(state->twostep_delay_resp_packet.receivetimestamp, &remote_rxtime); + ptp_format_to_timespec(msg->origintimestamp, &remote_txtime); + peer_delay_reflection = timespec_delta_ns(&remote_txtime, &remote_rxtime); + peer_delay = (peer_delay_roundtrip - peer_delay_reflection) / 2; + + if (peer_delay >= 0 && peer_delay < CONFIG_NETUTILS_PTPD_MAX_PEER_DELAY_NS) + { + if (state->peer_delay_avgcount < + CONFIG_NETUTILS_PTPD_DELAYREQ_AVGCOUNT) + { + state->peer_delay_avgcount++; + } + + state->peer_delay_ns += (peer_delay - state->peer_delay_ns) + / state->peer_delay_avgcount; + + ptpinfo("Peer delay: %ld ns (avg: %ld ns)\n", + (long)peer_delay, (long)state->peer_delay_ns); + } + else + { + ptpwarn("Peer delay out of range: %lld ns\n", + (long long)peer_delay); + } + + return OK; +} + /* Determine received packet type and process it */ static int ptp_process_rx_packet(FAR struct ptp_state_s *state, @@ -1755,7 +1928,8 @@ static int ptp_process_rx_packet(FAR struct ptp_state_s *state, } clock_gettime(CLOCK_MONOTONIC, &state->last_received_multicast); - ESP_LOGI("proc_rx_packet", "rxtime: %lld.%09ld", (long long)state->rxtime.tv_sec, state->rxtime.tv_nsec); + + /* Rout the packet to the appropriate handler */ switch (state->rxbuf.header.messagetype & PTP_MSGTYPE_MASK) { @@ -1768,14 +1942,17 @@ static int ptp_process_rx_packet(FAR struct ptp_state_s *state, case PTP_MSGTYPE_SYNC: ptpinfo("Got sync packet, seq %ld\n", (long)ptp_get_sequence(&state->rxbuf.header)); + if (!state->selected_source_valid) { return OK; } // ignore if operating as a server return ptp_process_sync(state, &state->rxbuf.sync); case PTP_MSGTYPE_FOLLOW_UP: ptpinfo("Got follow-up packet, seq %ld\n", (long)ptp_get_sequence(&state->rxbuf.header)); + if (!state->selected_source_valid) { return OK; } // ignore if operating as a server return ptp_process_followup(state, &state->rxbuf.follow_up); case PTP_MSGTYPE_DELAY_RESP: + case PTP_MSGTYPE_PDELAY_RESP: ptpinfo("Got delay-resp, seq %ld\n", (long)ptp_get_sequence(&state->rxbuf.header)); return ptp_process_delay_resp(state, &state->rxbuf.delay_resp); @@ -1783,11 +1960,17 @@ static int ptp_process_rx_packet(FAR struct ptp_state_s *state, #if defined(CONFIG_NETUTILS_PTPD_SERVER) || defined(CONFIG_NETUTILS_PTPD_GPTP_PROFILE) // gPTP always responds to delay requests case PTP_MSGTYPE_DELAY_REQ: + case PTP_MSGTYPE_PDELAY_REQ: ptpinfo("Got delay req, seq %ld\n", (long)ptp_get_sequence(&state->rxbuf.header)); return ptp_process_delay_req(state, &state->rxbuf.delay_req); #endif + case PTP_MSGTYPE_PDELAY_RESP_FOLLOW_UP: // + ptpinfo("Got peer delay resp follow-up, seq %ld\n", + (long)ptp_get_sequence(&state->rxbuf.header)); + return ptp_process_delay_resp_follow_up(state, &state->rxbuf.delay_resp_follow_up); + default: ptpinfo("Ignoring unknown PTP packet type: 0x%02x\n", state->rxbuf.header.messagetype); @@ -1876,6 +2059,7 @@ static void ptp_process_statusreq(FAR struct ptp_state_s *state) status->last_adjtime_ns = state->last_adjtime_ns; status->drift_ppb = state->drift_ppb; status->path_delay_ns = state->path_delay_ns; + status->peer_delay_ns = state->peer_delay_ns; /* Copy timestamps */ diff --git a/examples/ethernet/ptp/components/ptpd/ptpv2.h b/examples/ethernet/ptp/components/ptpd/ptpv2.h index 03fdc845c827..d85313461ed4 100644 --- a/examples/ethernet/ptp/components/ptpd/ptpv2.h +++ b/examples/ethernet/ptp/components/ptpd/ptpv2.h @@ -46,9 +46,6 @@ #define PTP_UDP_PORT_EVENT 319 #define PTP_UDP_PORT_INFO 320 -// gPTP settings (may move to kconfig) -#define CONFIG_NETUTILS_PTPD_GPTP_PROFILE 1 - /* Multicast address to send to: 224.0.1.129 */ #define PTP_MULTICAST_ADDR ((in_addr_t)0xE0000181) @@ -56,31 +53,25 @@ /* Multicast MAC addresses for PTP */ #define LLDP_MULTICAST_ADDR (uint8_t[6]){0x01, 0x80, 0xC2, 0x00, 0x00, 0x0e} // for all messages in case of gPTP -#define PTP4L_MULTICAST_ADDR (uint8_t[6]){0x01, 0x1B, 0x19, 0x00, 0x00, 0x00} // for sync, announce, follow_up in case of PTP4L +#define PTP4L_MULTICAST_ADDR (uint8_t[6]){0x01, 0x1B, 0x19, 0x00, 0x00, 0x00} // for sync, announce, follow_up (non-gPTP) /* Message types */ -#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE -#define PTP_MSGTYPE_MASK 0x1F -#define PTP_MSGTYPE_SYNC 0x10 -#define PTP_MSGTYPE_FOLLOW_UP 0x18 -#define PTP_MSGTYPE_ANNOUNCE 0x1b -#define PTP_MSGTYPE_DELAY_REQ 0x12 // re-using delay req for pdelay req -#define PTP_MSGTYPE_DELAY_RESP 0x13 // re-using delay resp for pdelay resp -#define PTP_MSGTYPE_DELAY_RESP_FOLLOW_UP 0x1a // actually pdelay response follow-up -#else -#define PTP_MSGTYPE_MASK 0x0F -#define PTP_MSGTYPE_SYNC 0x00 -#define PTP_MSGTYPE_FOLLOW_UP 0x08 -#define PTP_MSGTYPE_ANNOUNCE 0x0b -#define PTP_MSGTYPE_DELAY_REQ 0x01 -#define PTP_MSGTYPE_DELAY_RESP 0x09 -#endif +#define PTP_MSGTYPE_MASK 0x0F +#define PTP_MSGTYPE_SYNC 0x00 +#define PTP_MSGTYPE_FOLLOW_UP 0x08 +#define PTP_MSGTYPE_ANNOUNCE 0x0b +#define PTP_MSGTYPE_DELAY_REQ 0x01 +#define PTP_MSGTYPE_DELAY_RESP 0x09 +#define PTP_MSGTYPE_PDELAY_REQ 0x02 // only used in gPTP +#define PTP_MSGTYPE_PDELAY_RESP 0x03 // only used in gPTP +#define PTP_MSGTYPE_PDELAY_RESP_FOLLOW_UP 0x1a // only used in gPTP /* Message flags */ -#define PTP_FLAGS0_TWOSTEP (1 << 1) -#define PTP_FLAGS1_PTP_TIMESCALE (1 << 3) +#define PTP_FLAGS0_TWOSTEP (1 << 1) // flag indicating there will be a follow-up message +#define PTP_FLAGS1_PTP_TIMESCALE (1 << 3) // flag indicating use of PTP timescale (gPTP required) +#define PTP_MSGTYPE_SDOID_GPTP (1 << 4) // flag indicating a gPTP message /**************************************************************************** * Public Types @@ -166,7 +157,7 @@ struct ptp_follow_up_s uint8_t informationtlv[32]; // gPTP required }; -/* DelayReq: request delay measurement */ +/* DelayReq: request delay measurement (path delay or peer delay) */ struct ptp_delay_req_s { @@ -174,7 +165,7 @@ struct ptp_delay_req_s uint8_t origintimestamp[10]; // in gPTP profile, this will be ignored }; -/* DelayResp: response to DelayReq */ +/* DelayResp: response to DelayReq (path delay or peer delay)*/ struct ptp_delay_resp_s { @@ -184,7 +175,7 @@ struct ptp_delay_resp_s uint8_t reqportindex[2]; }; -/* DelayResp: follow up to DelayResp */ +/* DelayResp: follow up to DelayResp (gPTP only)*/ struct ptp_delay_resp_follow_up_s {