From 2c1ed4443da889d8502e6d8ca0efdd8fd50eeaa1 Mon Sep 17 00:00:00 2001 From: Scramble Tools <162384439+scrambletools@users.noreply.github.com> Date: Sun, 8 Dec 2024 17:48:05 -0800 Subject: [PATCH] Added support for gPTP This includes handling peer delay messages and TLVs in announce and follow up messages. Also, handles simpler BMCA in gPTP case. Currently it seems the HW timestamp is not showing in the IREC in the case of received frames, so that made it difficult to test interop with other gPTP devices. --- examples/ethernet/ptp/components/ptpd/ptpd.c | 189 +++++++++++++----- examples/ethernet/ptp/components/ptpd/ptpv2.h | 72 ++++++- examples/ethernet/ptp/sdkconfig.defaults | 7 + 3 files changed, 207 insertions(+), 61 deletions(-) diff --git a/examples/ethernet/ptp/components/ptpd/ptpd.c b/examples/ethernet/ptp/components/ptpd/ptpd.c index c20657338a55..708ec0c18d9f 100644 --- a/examples/ethernet/ptp/components/ptpd/ptpd.c +++ b/examples/ethernet/ptp/components/ptpd/ptpd.c @@ -132,6 +132,18 @@ typedef struct } pi_cntrl_t; #endif // ESP_PTP +typedef union +{ + struct ptp_header_s header; + struct ptp_announce_s announce; + struct ptp_sync_s sync; + struct ptp_follow_up_s follow_up; + struct ptp_delay_req_s delay_req; + struct ptp_delay_resp_s delay_resp; + struct ptp_delay_resp_follow_up_s delay_resp_follow_up; + uint8_t raw[128]; +} ptp_msgbuf; + /* Carrier structure for querying PTPD status */ struct ptpd_statusreq_s @@ -226,16 +238,7 @@ struct ptp_state_s /* Latest received packet and its timestamp (CLOCK_REALTIME) */ struct timespec rxtime; - union - { - struct ptp_header_s header; - struct ptp_announce_s announce; - struct ptp_sync_s sync; - struct ptp_follow_up_s follow_up; - struct ptp_delay_req_s delay_req; - struct ptp_delay_resp_s delay_resp; - uint8_t raw[128]; - } rxbuf; + ptp_msgbuf rxbuf; #ifndef ESP_PTP uint8_t rxcmsg[CMSG_LEN(sizeof(struct timeval))]; @@ -288,10 +291,14 @@ static struct ptp_state_s *s_state; 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 = { - //.dest.addr = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x0E}, // TODO only for Pdelay_Req, Pdelay_Resp and Pdelay_Resp_Follow_Up - .dest.addr = {0x01, 0x1B, 0x19, 0x00, 0x00, 0x00}, // All except peer delay messages, ptp4l sends everything at this addr .type = htons(ETH_TYPE_PTP) }; + + #ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + memcpy(ð_hdr.dest.addr, LLDP_MULTICAST_ADDR, ETH_ADDR_LEN); + #else + memcpy(ð_hdr.dest.addr, PTP4L_MULTICAST_ADDR, ETH_ADDR_LEN); + #endif memcpy(ð_hdr.src.addr, state->intf_hw_addr, ETH_ADDR_LEN); memcpy(eth_frame, ð_hdr, sizeof(eth_hdr)); @@ -327,6 +334,7 @@ static int ptp_net_send(FAR struct ptp_state_s *state, void *ptp_msg, uint16_t p if (ret > 0 && ts && ts_info->type == L2TAP_IREC_TIME_STAMP) { *ts = *(struct timespec *)ts_info->data; + ESP_LOGD("net_send", "ts is %lld.%09ld", (long long)ts->tv_sec, ts->tv_nsec); } return ret; @@ -359,6 +367,8 @@ static int ptp_net_recv(FAR struct ptp_state_s *state, void *ptp_msg, uint16_t p if (ret > 0 && ts && ts_info->type == L2TAP_IREC_TIME_STAMP) { *ts = *(struct timespec *)ts_info->data; + ESP_LOGD("net_recv", "ts is %lld.%09ld", (long long)ts->tv_sec, ts->tv_nsec); + /* GETTING ZERO VALUES FOR TS !!! */ } memcpy(ptp_msg, ð_frame[ETH_HEADER_LEN], ret); @@ -427,12 +437,17 @@ static bool is_better_clock(FAR const struct ptp_announce_s *a, FAR const struct ptp_announce_s *b) { if (a->gm_priority1 < b->gm_priority1 /* Main priority field */ +#ifndef CONFIG_NETUTILS_PTPD_GPTP_PROFILE || a->gm_quality[0] < b->gm_quality[0] /* Clock class */ || a->gm_quality[1] < b->gm_quality[1] /* Clock accuracy */ || a->gm_quality[2] < b->gm_quality[2] /* Clock variance high byte */ || a->gm_quality[3] < b->gm_quality[3] /* Clock variance low byte */ || a->gm_priority2 < b->gm_priority2 /* Sub priority field */ - || memcmp(a->gm_identity, b->gm_identity, sizeof(a->gm_identity)) < 0) +#endif + || memcmp(a->gm_identity, b->gm_identity, sizeof(a->gm_identity)) < 0 +#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + || ((a->stepsremoved[0] << 8) | a->stepsremoved[1]) < ((b->stepsremoved[0] << 8) | b->stepsremoved[1])) +#endif { return true; } @@ -942,10 +957,21 @@ static int ptp_send_announce(FAR struct ptp_state_s *state) msg.header.messagetype = PTP_MSGTYPE_ANNOUNCE; msg.header.messagelength[1] = sizeof(msg); +#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + msg.header.flags[1] = PTP_FLAGS1_PTP_TIMESCALE; +#endif + ptp_increment_sequence(&state->announce_seq, &msg.header); ptp_gettime(state, &ts); timespec_to_ptp_format(&ts, msg.origintimestamp); + /* Add the path trace TLV */ + struct ptp_pathtrace_tlv_s pathtrace_tlv; + pathtrace_tlv.type[1] = 8; // Path trace + pathtrace_tlv.length[1] = 8; // 8 bytes + memcpy(pathtrace_tlv.pathsequence, state->own_identity.gm_identity, sizeof(state->own_identity.gm_identity)); + msg.pathtracetlv = pathtrace_tlv; + #ifdef ESP_PTP ret = ptp_net_send(state, &msg, sizeof(msg), NULL); #else @@ -974,7 +1000,7 @@ static int ptp_send_sync(FAR struct ptp_state_s *state) struct msghdr txhdr; struct iovec txiov; #endif // !ESP_PTP - struct ptp_sync_s msg; + ptp_msgbuf msg; #ifndef ESP_PTP struct sockaddr_in addr; #endif // !ESP_PTP @@ -996,11 +1022,14 @@ static int ptp_send_sync(FAR struct ptp_state_s *state) memset(&msg, 0, sizeof(msg)); msg.header = state->own_identity.header; msg.header.messagetype = PTP_MSGTYPE_SYNC; - msg.header.messagelength[1] = sizeof(msg); + msg.header.messagelength[1] = sizeof(struct ptp_sync_s); -#ifdef CONFIG_NETUTILS_PTPD_TWOSTEP_SYNC +#if defined(CONFIG_NETUTILS_PTPD_TWOSTEP_SYNC) || defined(CONFIG_NETUTILS_PTPD_GPTP_PROFILE) // gPTP always uses two-step sync msg.header.flags[0] = PTP_FLAGS0_TWOSTEP; #endif +#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + msg.header.flags[1] = PTP_FLAGS1_PTP_TIMESCALE; +#endif #ifndef ESP_PTP txhdr.msg_name = &addr; @@ -1017,10 +1046,10 @@ static int ptp_send_sync(FAR struct ptp_state_s *state) ptp_increment_sequence(&state->sync_seq, &msg.header); ptp_gettime(state, &ts); - timespec_to_ptp_format(&ts, msg.origintimestamp); + timespec_to_ptp_format(&ts, msg.sync.origintimestamp); #ifdef ESP_PTP - ret = ptp_net_send(state, &msg, sizeof(msg), &ts); + ret = ptp_net_send(state, &msg, sizeof(struct ptp_sync_s), &ts); #else ret = sendmsg(state->tx_socket, &txhdr, 0); #endif // ESP_PTP @@ -1030,25 +1059,40 @@ static int ptp_send_sync(FAR struct ptp_state_s *state) return ret; } -#ifdef CONFIG_NETUTILS_PTPD_TWOSTEP_SYNC +/* gPTP profile requires 2-step sync */ +#if defined(CONFIG_NETUTILS_PTPD_TWOSTEP_SYNC) || defined(CONFIG_NETUTILS_PTPD_GPTP_PROFILE) #ifndef ESP_PTP /* Get timestamp after send completes and send follow-up message * * TODO: Implement SO_TIMESTAMPING and use the actual tx timestamp here. */ - ptp_gettime(state, &ts); #endif // !ESP_PTP - timespec_to_ptp_format(&ts, msg.origintimestamp); + timespec_to_ptp_format(&ts, msg.follow_up.origintimestamp); msg.header.messagetype = PTP_MSGTYPE_FOLLOW_UP; - msg.header.flags[0] = 0; + 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 + struct ptp_info_tlv_s info_tlv; + memset(&info_tlv, 0, sizeof(info_tlv)); + info_tlv.type[1] = 3; // Organization extension + info_tlv.length[1] = 0x1c; // 28 bytes + uint8_t orgidentity[] = {0x00,0x80,0xc2}; // 32962 (gPTP required value) + memcpy(info_tlv.orgidentity, orgidentity, sizeof(orgidentity)); + info_tlv.orgsubtype[2] = 1; // gPTP required value + /* Remaining fields not used yet */ + memcpy(msg.follow_up.informationtlv, &info_tlv, sizeof(info_tlv)); + #ifndef ESP_PTP addr.sin_port = HTONS(PTP_UDP_PORT_INFO); ret = sendto(state->tx_socket, &msg, sizeof(msg), 0, (struct sockaddr *)&addr, sizeof(addr)); #else - ret = ptp_net_send(state, &msg, sizeof(msg), NULL); + + /* Send the follow up message */ + + ret = ptp_net_send(state, &msg, sizeof(struct ptp_follow_up_s), NULL); #endif // !ESP_PTP if (ret < 0) { @@ -1154,7 +1198,7 @@ static int ptp_periodic_send(FAR struct ptp_state_s *state) } #endif /* CONFIG_NETUTILS_PTPD_SERVER */ -#ifdef CONFIG_NETUTILS_PTPD_SEND_DELAYREQ +#if defined(CONFIG_NETUTILS_PTPD_SEND_DELAYREQ) || defined(CONFIG_NETUTILS_PTPD_GPTP_PROFILE) // gPTP always sends delay requests if (state->selected_source_valid && state->can_send_delayreq) { struct timespec time_now; @@ -1519,20 +1563,23 @@ static int ptp_process_followup(FAR struct ptp_state_s *state, } static int ptp_process_delay_req(FAR struct ptp_state_s *state, - FAR struct ptp_delay_req_s *msg) + FAR struct ptp_delay_req_s *req) { - struct ptp_delay_resp_s resp; + ptp_msgbuf msg; + struct timespec ts; #ifndef ESP_PTP struct sockaddr_in addr; #endif // !ESP_PTP int ret; +#ifndef CONFIG_NETUTILS_PTPD_GPTP_PROFILE // gPTP always responds to delay requests if (state->selected_source_valid) { /* We are operating as a client, ignore delay requests */ return OK; } +#endif // !CONFIG_NETUTILS_PTPD_GPTP_PROFILE #ifndef ESP_PTP addr.sin_family = AF_INET; @@ -1540,38 +1587,72 @@ static int ptp_process_delay_req(FAR struct ptp_state_s *state, addr.sin_port = HTONS(PTP_UDP_PORT_INFO); #endif // !ESP_PTP - memset(&resp, 0, sizeof(resp)); - resp.header = state->own_identity.header; - resp.header.messagetype = PTP_MSGTYPE_DELAY_RESP; - resp.header.messagelength[1] = sizeof(resp); - timespec_to_ptp_format(&state->rxtime, resp.receivetimestamp); - memcpy(resp.reqidentity, msg->header.sourceidentity, - sizeof(resp.reqidentity)); - memcpy(resp.reqportindex, msg->header.sourceportindex, - sizeof(resp.reqportindex)); - memcpy(resp.header.sequenceid, msg->header.sequenceid, - sizeof(resp.header.sequenceid)); - resp.header.logmessageinterval = CONFIG_NETUTILS_PTPD_DELAYRESP_INTERVAL; + memset(&msg, 0, sizeof(msg)); + msg.header = state->own_identity.header; + msg.header.messagetype = PTP_MSGTYPE_DELAY_RESP; + 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 +#endif + timespec_to_ptp_format(&state->rxtime, msg.delay_resp.receivetimestamp); + memcpy(msg.delay_resp.reqidentity, req->header.sourceidentity, + sizeof(req->header.sourceidentity)); + memcpy(msg.delay_resp.reqportindex, req->header.sourceportindex, + sizeof(req->header.sourceportindex)); + memcpy(msg.header.sequenceid, req->header.sequenceid, + sizeof(req->header.sequenceid)); + +#ifdef CONFIG_NETUTILS_PTPD_GPTP_PROFILE + msg.header.logmessageinterval = 0; // gPTP required value +#else + msg.header.logmessageinterval = CONFIG_NETUTILS_PTPD_DELAYRESP_INTERVAL; +#endif // CONFIG_NETUTILS_PTPD_GPTP_PROFILE + + /* Send the response message */ #ifdef ESP_PTP - ret = ptp_net_send(state, &resp, sizeof(resp), NULL); + ret = ptp_net_send(state, &msg, sizeof(struct ptp_delay_resp_s), &ts); #else - ret = sendto(state->tx_socket, &resp, sizeof(resp), 0, + ret = sendto(state->tx_socket, &msg, sizeof(msg), 0, (FAR struct sockaddr *)&addr, sizeof(addr)); #endif // ESP_PTP if (ret < 0) { ptperr("sendto failed: %d", errno); + return ret; } - else + + 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.messagelength[1] = sizeof(struct ptp_delay_resp_follow_up_s); + msg.header.flags[0] = 0; // Reset 2-step flag + + /* Send the response follow-up message */ + + ret = ptp_net_send(state, &msg, sizeof(struct ptp_delay_resp_follow_up_s), NULL); + if (ret < 0) { - clock_gettime(CLOCK_MONOTONIC, &state->last_transmitted_delayresp); - ptpinfo("Sent delay resp, seq %ld\n", - (long)ptp_get_sequence(&msg->header)); + ptperr("sendto for delay response follow-up message failed: %d\n", errno); + return ret; } + ptpinfo("Sent response + response follow-up, seq %ld\n", + (long)ptp_get_sequence(&msg.header)); +#else + ptpinfo("Sent delay resp, seq %ld\n", + (long)ptp_get_sequence(&req->header)); +#endif /* CONFIG_NETUTILS_PTPD_GPTP_PROFILE */ - return ret; + return OK; } static int ptp_process_delay_resp(FAR struct ptp_state_s *state, @@ -1581,7 +1662,6 @@ static int ptp_process_delay_resp(FAR struct ptp_state_s *state, int64_t sync_delay; struct timespec remote_rxtime; uint16_t sequence; - int interval; if (!state->selected_source_valid || memcmp(msg->header.sourceidentity, @@ -1606,6 +1686,8 @@ static int ptp_process_delay_resp(FAR struct ptp_state_s *state, /* 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); @@ -1633,8 +1715,10 @@ 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) { interval = (1 << msg->header.logmessageinterval); @@ -1644,9 +1728,9 @@ static int ptp_process_delay_resp(FAR struct ptp_state_s *state, interval = 4096; /* Refuse to obey excessively long intervals */ } - /* Randomize up to 2x nominal delay) */ - + /* Randomize up to 2x nominal delay */ state->delayreq_interval = interval + (random() % interval); +#endif // CONFIG_NETUTILS_PTPD_GPTP_PROFILE return OK; } @@ -1671,10 +1755,11 @@ 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); switch (state->rxbuf.header.messagetype & PTP_MSGTYPE_MASK) { -#ifdef CONFIG_NETUTILS_PTPD_CLIENT +#if defined(CONFIG_NETUTILS_PTPD_CLIENT) || defined(CONFIG_NETUTILS_PTPD_GPTP_PROFILE) // gPTP always acts as a client case PTP_MSGTYPE_ANNOUNCE: ptpinfo("Got announce packet, seq %ld\n", (long)ptp_get_sequence(&state->rxbuf.header)); @@ -1696,7 +1781,7 @@ static int ptp_process_rx_packet(FAR struct ptp_state_s *state, return ptp_process_delay_resp(state, &state->rxbuf.delay_resp); #endif -#ifdef CONFIG_NETUTILS_PTPD_SERVER +#if defined(CONFIG_NETUTILS_PTPD_SERVER) || defined(CONFIG_NETUTILS_PTPD_GPTP_PROFILE) // gPTP always responds to delay requests case PTP_MSGTYPE_DELAY_REQ: ptpinfo("Got delay req, seq %ld\n", (long)ptp_get_sequence(&state->rxbuf.header)); @@ -1945,7 +2030,7 @@ static int ptp_daemon(int argc, FAR char** argv) state->selected_source_valid = is_selected_source_valid(state); ptp_process_statusreq(state); - } + } // while (!state->stop) ptp_destroy_state(state); free(state); diff --git a/examples/ethernet/ptp/components/ptpd/ptpv2.h b/examples/ethernet/ptp/components/ptpd/ptpv2.h index 30cf527808ad..03fdc845c827 100644 --- a/examples/ethernet/ptp/components/ptpd/ptpv2.h +++ b/examples/ethernet/ptp/components/ptpd/ptpv2.h @@ -46,31 +46,73 @@ #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) +/* 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 + /* Message types */ -#define PTP_MSGTYPE_MASK 0x0F -#define PTP_MSGTYPE_SYNC 0 -#define PTP_MSGTYPE_DELAY_REQ 1 -#define PTP_MSGTYPE_FOLLOW_UP 8 -#define PTP_MSGTYPE_DELAY_RESP 9 -#define PTP_MSGTYPE_ANNOUNCE 11 +#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 /* Message flags */ #define PTP_FLAGS0_TWOSTEP (1 << 1) +#define PTP_FLAGS1_PTP_TIMESCALE (1 << 3) /**************************************************************************** * Public Types ****************************************************************************/ -/* Defined in IEEE 1588-2008 Precision Time Protocol +/* Defined in IEEE 1588-2008 Precision Time Protocol and IEEE 802.1AS-2011 * All multi-byte fields are big-endian. */ +/* Path trace TLV for gPTP follow up messages */ + +struct ptp_pathtrace_tlv_s +{ + uint8_t type[2]; + uint8_t length[2]; + uint8_t pathsequence[8]; // this can have more but gPTP endpoints will ignore +}; + +/* Information TLV for gPTP announce messages */ + +struct ptp_info_tlv_s +{ + uint8_t type[2]; + uint8_t length[2]; + uint8_t orgidentity[3]; + uint8_t orgsubtype[3]; + uint8_t cumulativescaledrateoffset[4]; + uint8_t gmtimebaseindicator[2]; + uint8_t lastgmphasechange[12]; + uint8_t scaledlastgmfreqchange[4]; +}; + /* Common header for all message types */ struct ptp_header_s @@ -104,6 +146,7 @@ struct ptp_announce_s uint8_t gm_identity[8]; uint8_t stepsremoved[2]; uint8_t timesource; + struct ptp_pathtrace_tlv_s pathtracetlv; // gPTP required }; /* Sync: transmit timestamp from master clock */ @@ -111,7 +154,7 @@ struct ptp_announce_s struct ptp_sync_s { struct ptp_header_s header; - uint8_t origintimestamp[10]; + uint8_t origintimestamp[10]; // in gPTP profile, this will be ignored }; /* FollowUp: actual timestamp of when sync message was sent */ @@ -120,6 +163,7 @@ struct ptp_follow_up_s { struct ptp_header_s header; uint8_t origintimestamp[10]; + uint8_t informationtlv[32]; // gPTP required }; /* DelayReq: request delay measurement */ @@ -127,7 +171,7 @@ struct ptp_follow_up_s struct ptp_delay_req_s { struct ptp_header_s header; - uint8_t origintimestamp[10]; + uint8_t origintimestamp[10]; // in gPTP profile, this will be ignored }; /* DelayResp: response to DelayReq */ @@ -140,4 +184,14 @@ struct ptp_delay_resp_s uint8_t reqportindex[2]; }; +/* DelayResp: follow up to DelayResp */ + +struct ptp_delay_resp_follow_up_s +{ + struct ptp_header_s header; + uint8_t origintimestamp[10]; + uint8_t reqidentity[8]; + uint8_t reqportindex[2]; +}; + #endif /* __APPS_NETUTILS_PTPD_PTPV2_H */ diff --git a/examples/ethernet/ptp/sdkconfig.defaults b/examples/ethernet/ptp/sdkconfig.defaults index 0f922b582422..fbc30f4f1942 100644 --- a/examples/ethernet/ptp/sdkconfig.defaults +++ b/examples/ethernet/ptp/sdkconfig.defaults @@ -8,3 +8,10 @@ CONFIG_EXAMPLE_ETH_PHY_IP101=y CONFIG_NETUTILS_PTPD=y CONFIG_NETUTILS_PTPD_CLIENT=y CONFIG_NETUTILS_PTPD_SERVER=y + +CONFIG_NETUTILS_PTPD_PRIORITY1=246 +CONFIG_NETUTILS_PTPD_SERVERPRIO=100 +CONFIG_NETUTILS_PTPD_TIMEOUT_MS=10000 +CONFIG_NETUTILS_PTPD_SETTIME_THRESHOLD_MS=100 +CONFIG_EXAMPLE_PTP_PULSE_GPIO=20 +CONFIG_EXAMPLE_PTP_PULSE_WIDTH_NS=250000000