flexPTP 1.0
An IEEE 1588 PTP implementation designed for microcontrollers
Loading...
Searching...
No Matches
msg_utils.c
Go to the documentation of this file.
1/* (C) AndrĂ¡s Wiesner, 2020-2022 */
2
3#include "ptp_types.h"
4#include "format_utils.h"
5
6#include <string.h>
7
8#include "msg_utils.h"
9#include "ptp_defs.h"
10
11// load ptp flags from bitfield
12void ptp_load_flags(PtpFlags *pFlags, uint16_t bitfield) {
14#define GET_FLAG_FROM_BITFIELD(flag, n) (pFlags->flag) = (bitfield >> (n)) & 1
16
17 GET_FLAG_FROM_BITFIELD(PTP_SECURITY, 15);
18 GET_FLAG_FROM_BITFIELD(PTP_ProfileSpecific_2, 14);
19 GET_FLAG_FROM_BITFIELD(PTP_ProfileSpecific_1, 13);
20 GET_FLAG_FROM_BITFIELD(PTP_UNICAST, 10);
21 GET_FLAG_FROM_BITFIELD(PTP_TWO_STEP, 9);
22 GET_FLAG_FROM_BITFIELD(PTP_ALTERNATE_MASTER, 8);
23 GET_FLAG_FROM_BITFIELD(FREQUENCY_TRACEABLE, 7);
24 GET_FLAG_FROM_BITFIELD(TIME_TRACEABLE, 4);
25 GET_FLAG_FROM_BITFIELD(PTP_TIMESCALE, 3);
26 GET_FLAG_FROM_BITFIELD(PTP_UTC_REASONABLE, 2);
27 GET_FLAG_FROM_BITFIELD(PTP_LI_59, 1);
28 GET_FLAG_FROM_BITFIELD(PTP_LI_61, 0);
29}
30
31// write flags to bitfield
32uint16_t ptp_write_flags(const PtpFlags *pFlags) {
34#define SET_BIT_IN_FLAG_BITFIELD(flag, n) bitfield |= (pFlags->flag) ? (1 << (n)) : 0
36
37 uint16_t bitfield = 0;
38 SET_BIT_IN_FLAG_BITFIELD(PTP_SECURITY, 15);
39 SET_BIT_IN_FLAG_BITFIELD(PTP_ProfileSpecific_2, 14);
40 SET_BIT_IN_FLAG_BITFIELD(PTP_ProfileSpecific_1, 13);
41 SET_BIT_IN_FLAG_BITFIELD(PTP_UNICAST, 10);
42 SET_BIT_IN_FLAG_BITFIELD(PTP_TWO_STEP, 9);
43 SET_BIT_IN_FLAG_BITFIELD(PTP_ALTERNATE_MASTER, 8);
44 SET_BIT_IN_FLAG_BITFIELD(FREQUENCY_TRACEABLE, 7);
45 SET_BIT_IN_FLAG_BITFIELD(TIME_TRACEABLE, 4);
46 SET_BIT_IN_FLAG_BITFIELD(PTP_TIMESCALE, 3);
47 SET_BIT_IN_FLAG_BITFIELD(PTP_UTC_REASONABLE, 2);
48 SET_BIT_IN_FLAG_BITFIELD(PTP_LI_59, 1);
49 SET_BIT_IN_FLAG_BITFIELD(PTP_LI_61, 0);
50
51 return bitfield;
52}
53
54// extract fields from a PTP header
55void ptp_extract_header(PtpHeader *pHeader, const void *pPayload) {
56 // cast header to byte accessible form
57 uint8_t *p = (uint8_t *)pPayload;
58
59 uint16_t flags;
60
61 // copy header fields
62 memcpy(&pHeader->messageType, p + 0, 1);
63 memcpy(&pHeader->versionPTP, p + 1, 1);
64 memcpy(&pHeader->messageLength, p + 2, 2);
65 memcpy(&pHeader->domainNumber, p + 4, 1);
66 memcpy(&flags, p + 6, 2);
67 memcpy(&pHeader->correction_ns, p + 8, 8);
68 memcpy(&pHeader->clockIdentity, p + 20, 8);
69 memcpy(&pHeader->sourcePortID, p + 28, 2);
70 memcpy(&pHeader->sequenceID, p + 30, 2);
71 memcpy(&pHeader->control, p + 32, 1);
72 memcpy(&pHeader->logMessagePeriod, p + 33, 1);
73
74 pHeader->transportSpecific = (0xf0 & pHeader->messageType) >> 4;
75 pHeader->messageType &= 0x0f;
76
77 // read flags
78 ptp_load_flags(&pHeader->flags, FLEXPTP_ntohs(flags));
79
80 // read correction field
81 pHeader->correction_subns = FLEXPTP_ntohll(pHeader->correction_ns) & 0xffff;
82 pHeader->correction_ns = FLEXPTP_ntohll(pHeader->correction_ns) >> 16;
83
84 pHeader->messageLength = FLEXPTP_ntohs(pHeader->messageLength);
85 pHeader->sourcePortID = FLEXPTP_ntohs(pHeader->sourcePortID);
86 pHeader->sequenceID = FLEXPTP_ntohs(pHeader->sequenceID);
87}
88
89// construct binary header from header structure
90void ptp_construct_binary_header(void *pData, const PtpHeader *pHeader) {
91 uint8_t *p = (uint8_t *)pData;
92 uint8_t firstByte, secondByte;
93
94 // host->network
95 uint16_t messageLength = FLEXPTP_htons(pHeader->messageLength);
96 uint16_t sourcePortID = FLEXPTP_htons(pHeader->sourcePortID);
97 uint16_t sequenceID = FLEXPTP_htons(pHeader->sequenceID);
98
99 // fill in flags
100 uint16_t flags = FLEXPTP_htons(ptp_write_flags(&pHeader->flags)); // convert from header fields
101
102 // fill in correction value
103 uint64_t correction = FLEXPTP_htonll((pHeader->correction_ns << 16) | (pHeader->correction_subns));
104
105 // copy fields
106 firstByte = (pHeader->transportSpecific << 4) | (pHeader->messageType & 0x0f);
107 memcpy(p, &firstByte, 1);
108 secondByte = (pHeader->minorVersionPTP << 4) | (pHeader->versionPTP & 0x0f);
109 memcpy(p + 1, &secondByte, 1);
110 memcpy(p + 2, &messageLength, 2);
111 memcpy(p + 4, &pHeader->domainNumber, 1);
112 memcpy(p + 6, &flags, 2);
113 memcpy(p + 8, &correction, 8);
114 memcpy(p + 20, &pHeader->clockIdentity, 8);
115 memcpy(p + 28, &sourcePortID, 2);
116 memcpy(p + 30, &sequenceID, 2);
117 memcpy(p + 32, &pHeader->control, 1);
118 memcpy(p + 33, &pHeader->logMessagePeriod, 1);
119}
120
121// extract announce message
122void ptp_extract_announce_message(PtpAnnounceBody *pAnnounce, void *pPayload) {
123 // cast header to byte accessible form
124 uint8_t *p = (uint8_t *)pPayload + (PTP_HEADER_LENGTH + PTP_TIMESTAMP_LENGTH);
125
126 // copy header fields
127 memcpy(&pAnnounce->currentUTCOffset, p + 0, 2);
128 memcpy(&pAnnounce->priority1, p + 3, 1);
129 memcpy(&pAnnounce->grandmasterClockClass, p + 4, 1);
130 memcpy(&pAnnounce->grandmasterClockAccuracy, p + 5, 1);
131 memcpy(&pAnnounce->grandmasterClockVariance, p + 6, 2);
132 memcpy(&pAnnounce->priority2, p + 8, 1);
133 memcpy(&pAnnounce->grandmasterClockIdentity, p + 9, 8);
134 memcpy(&pAnnounce->localStepsRemoved, p + 17, 2);
135 memcpy(&pAnnounce->timeSource, p + 19, 1);
136
137 pAnnounce->currentUTCOffset = FLEXPTP_ntohs(pAnnounce->currentUTCOffset);
140 pAnnounce->localStepsRemoved = FLEXPTP_ntohs(pAnnounce->localStepsRemoved);
141}
142
143void ptp_construct_binary_announce_message(void * pData, const PtpAnnounceBody * pAnnounce) {
144 // cast header to byte accessible form
145 uint8_t *p = (uint8_t *)pData + (PTP_HEADER_LENGTH + PTP_TIMESTAMP_LENGTH);
146
147 // convert to big endian
148 uint16_t currentUTCOffset = FLEXPTP_ntohs(pAnnounce->currentUTCOffset);
149 uint16_t grandmasterClockVariance = FLEXPTP_ntohs(pAnnounce->grandmasterClockVariance);
150 uint64_t grandmasterClockIdentity = FLEXPTP_ntohll(pAnnounce->grandmasterClockIdentity);
151 uint16_t localStepsRemoved = FLEXPTP_ntohs(pAnnounce->localStepsRemoved);
152
153 // copy header fields
154 memcpy(p + 0, &currentUTCOffset, 2);
155 memcpy(p + 3, &pAnnounce->priority1, 1);
156 memcpy(p + 4, &pAnnounce->grandmasterClockClass, 1);
157 memcpy(p + 5, &pAnnounce->grandmasterClockAccuracy, 1);
158 memcpy(p + 6, &grandmasterClockVariance, 2);
159 memcpy(p + 8, &pAnnounce->priority2, 1);
160 memcpy(p + 9, &grandmasterClockIdentity, 8);
161 memcpy(p + 17, &localStepsRemoved, 2);
162 memcpy(p + 19, &pAnnounce->timeSource, 1);
163}
164
165// write n timestamps following the header in to packet
166void ptp_write_binary_timestamps(void *pPayload, const TimestampI *ts, uint8_t n) {
167 uint8_t *p = ((uint8_t *)pPayload) + PTP_HEADER_LENGTH;
168
169 // write n times
170 uint8_t i;
171 for (i = 0; i < n; i++) {
172 // get timestamp data
173 uint64_t sec = FLEXPTP_htonll(ts->sec << 16);
174 uint64_t nanosec = FLEXPTP_htonl(ts->nanosec);
175
176 // fill in time data
177 memcpy(p, &sec, 6); // 48-bit
178 p += 6;
179
180 memcpy(p, &nanosec, 4);
181 p += 4;
182
183 // step onto next element
184 ts++;
185 }
186}
187
188// extract n timestamps from a message
189void ptp_extract_timestamps(TimestampI *ts, void *pPayload, uint8_t n) {
190 uint8_t *p = ((uint8_t *)pPayload) + PTP_HEADER_LENGTH; // pointer at the beginning of first timestamp
191
192 // read n times
193 uint8_t i;
194 for (i = 0; i < n; i++) {
195 // seconds
196 ts->sec = 0;
197 memcpy(&ts->sec, p, 6); // 48-bit
198 p += 6;
199
200 // nanoseconds
201 memcpy(&ts->nanosec, p, 4);
202 p += 4;
203
204 // network->host
205 ts->sec = FLEXPTP_ntohll(ts->sec << 16);
206 ts->nanosec = FLEXPTP_ntohl(ts->nanosec);
207
208 // step to next timestamp
209 ts++;
210 }
211}
212
213// extract Delay_Resp ID data
215 uint8_t *p = (uint8_t *)pPayload;
216 memcpy(&pDRData->requestingSourceClockIdentity, p + 44, 8);
217 memcpy(&pDRData->requestingSourcePortIdentity, p + 52, 2);
218
219 // network->host
221}
222
223// insert Delay_Resp ID data
224void ptp_write_delay_resp_id_data(void *pPayload, const PtpDelay_RespIdentification *pDRData) {
225 uint8_t *p = (uint8_t *)pPayload;
226 uint16_t reqSrcPortId = FLEXPTP_htons(pDRData->requestingSourcePortIdentity); // host->network
227 memcpy(p + 44, &pDRData->requestingSourceClockIdentity, 8);
228 memcpy(p + 52, &reqSrcPortId, 2);
229}
230
231// clear flag structure
233 memset(pFlags, 0, sizeof(PtpFlags));
234}
uint64_t FLEXPTP_htonll(uint64_t in)
Definition: format_utils.c:35
uint64_t FLEXPTP_ntohll(uint64_t in)
Definition: format_utils.c:30
This module defines format conversion functions between network and host byte order and conversion fu...
void ptp_write_delay_resp_id_data(void *pPayload, const PtpDelay_RespIdentification *pDRData)
Definition: msg_utils.c:224
void ptp_construct_binary_announce_message(void *pData, const PtpAnnounceBody *pAnnounce)
Definition: msg_utils.c:143
void ptp_extract_header(PtpHeader *pHeader, const void *pPayload)
Definition: msg_utils.c:55
void ptp_extract_timestamps(TimestampI *ts, void *pPayload, uint8_t n)
Definition: msg_utils.c:189
void ptp_extract_announce_message(PtpAnnounceBody *pAnnounce, void *pPayload)
Definition: msg_utils.c:122
void ptp_read_delay_resp_id_data(PtpDelay_RespIdentification *pDRData, void *pPayload)
Definition: msg_utils.c:214
void ptp_load_flags(PtpFlags *pFlags, uint16_t bitfield)
Definition: msg_utils.c:12
void ptp_construct_binary_header(void *pData, const PtpHeader *pHeader)
Definition: msg_utils.c:90
uint16_t ptp_write_flags(const PtpFlags *pFlags)
Definition: msg_utils.c:32
void ptp_write_binary_timestamps(void *pPayload, const TimestampI *ts, uint8_t n)
Definition: msg_utils.c:166
void ptp_clear_flags(PtpFlags *pFlags)
Definition: msg_utils.c:232
This module defines functions that deal with actual PTP messages; they can extract or insert headers,...
In here reside a multitude of fundamental PTP-related constants and definitions.
#define FLEXPTP_htonl(a)
Definition: ptp_defs.h:163
#define PTP_HEADER_LENGTH
Length of the PTP header.
Definition: ptp_defs.h:40
#define PTP_TIMESTAMP_LENGTH
Length of a single timestamp.
Definition: ptp_defs.h:41
#define FLEXPTP_ntohl(a)
Definition: ptp_defs.h:169
#define FLEXPTP_ntohs(a)
Definition: ptp_defs.h:175
#define FLEXPTP_htons(a)
Definition: ptp_defs.h:171
This module defines the fundamental PTP message and state machine type, flags, bitfields and the PTP ...
Contents of a PTP Announce message without the common PTP header.
Definition: ptp_types.h:236
uint16_t currentUTCOffset
Current UTC Offset.
Definition: ptp_types.h:237
uint64_t grandmasterClockIdentity
Grandmaster Clock Identity.
Definition: ptp_types.h:243
uint8_t grandmasterClockClass
Grandmaster Clock Class.
Definition: ptp_types.h:239
uint8_t grandmasterClockAccuracy
Grandmaster Clock Accuracy.
Definition: ptp_types.h:240
uint16_t localStepsRemoved
Local Steps Removed.
Definition: ptp_types.h:244
uint16_t grandmasterClockVariance
Grandmaster Clock Variance.
Definition: ptp_types.h:241
uint8_t priority2
Priority 2.
Definition: ptp_types.h:242
uint8_t timeSource
Time Source.
Definition: ptp_types.h:245
uint8_t priority1
Priority 1.
Definition: ptp_types.h:238
Identification carrying Delay_Resp message.
Definition: ptp_types.h:120
uint64_t requestingSourceClockIdentity
Requesting Source Clock Identity.
Definition: ptp_types.h:121
uint16_t requestingSourcePortIdentity
Requesting Source Port Identity.
Definition: ptp_types.h:122
PTP flags structure.
Definition: ptp_types.h:54
PTP message header structure.
Definition: ptp_types.h:73
int8_t logMessagePeriod
Definition: ptp_types.h:114
uint8_t versionPTP
PTP version.
Definition: ptp_types.h:79
uint8_t messageType
ID.
Definition: ptp_types.h:75
uint64_t clockIdentity
Clock Identity.
Definition: ptp_types.h:102
uint16_t sequenceID
Sequence ID.
Definition: ptp_types.h:108
uint16_t messageLength
Length.
Definition: ptp_types.h:83
uint16_t sourcePortID
Source Port ID.
Definition: ptp_types.h:105
PtpFlags flags
Flags.
Definition: ptp_types.h:92
uint8_t minorVersionPTP
Definition: ptp_types.h:80
uint8_t control
Control.
Definition: ptp_types.h:111
uint64_t correction_ns
Correction nanoseconds.
Definition: ptp_types.h:95
uint8_t domainNumber
Domain.
Definition: ptp_types.h:86
uint32_t correction_subns
Correction subnanoseconds.
Definition: ptp_types.h:96
uint8_t transportSpecific
Transport Specific.
Definition: ptp_types.h:76
Timestamp (signed)
Definition: timeutils.h:29
int32_t nanosec
nanoseconds
Definition: timeutils.h:31
int64_t sec
seconds
Definition: timeutils.h:30