1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX PTP Client Component                                             */
16 /**                                                                       */
17 /**   Precision Time Protocol (PTP)                                       */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 /**************************************************************************/
23 /*                                                                        */
24 /*  APPLICATION INTERFACE DEFINITION                       RELEASE        */
25 /*                                                                        */
26 /*    nxd_ptp_client.h                                    PORTABLE C      */
27 /*                                                           6.1.3        */
28 /*  AUTHOR                                                                */
29 /*                                                                        */
30 /*    Yuxin Zhou, Microsoft Corporation                                   */
31 /*                                                                        */
32 /*  DESCRIPTION                                                           */
33 /*                                                                        */
34 /*    This file defines the NetX Precision Time Protocol (PTP)            */
35 /*    Client component, including all data types and external references. */
36 /*                                                                        */
37 /*  RELEASE HISTORY                                                       */
38 /*                                                                        */
39 /*    DATE              NAME                      DESCRIPTION             */
40 /*                                                                        */
41 /*  12-31-2020     Yuxin Zhou               Initial Version 6.1.3         */
42 /*                                                                        */
43 /**************************************************************************/
44 
45 #ifndef NXD_PTP_CLIENT_H
46 #define NXD_PTP_CLIENT_H
47 
48 
49 /* Include NetX and ThreadX definitions */
50 
51 #include "nx_api.h"
52 
53 
54 /* Determine if a C++ compiler is being used.  If so, ensure that standard
55    C is used to process the API information.  */
56 
57 #ifdef   __cplusplus
58 
59 /* Yes, C++ compiler is present.  Use standard C.  */
60 extern   "C" {
61 
62 #endif
63 
64 
65 /* PTP Client configurable options.  */
66 
67 
68 /* Set the client thread time slice.  */
69 
70 #ifndef NX_PTP_CLIENT_THREAD_TIME_SLICE
71 #define NX_PTP_CLIENT_THREAD_TIME_SLICE        TX_NO_TIME_SLICE
72 #endif
73 
74 
75 /* Define the PTP Client ID */
76 
77 #define NX_PTP_CLIENT_ID                       0x50545001UL
78 
79 
80 /* Define the PTP client internal timer frequency */
81 
82 #ifndef NX_PTP_CLIENT_TIMER_TICKS_PER_SECOND
83 #define NX_PTP_CLIENT_TIMER_TICKS_PER_SECOND   10
84 #endif
85 
86 
87 /* Define the maximum number of missing Announce packets before timeout */
88 
89 #ifndef NX_PTP_CLIENT_ANNOUNCE_RECEIPT_TIMEOUT
90 #define NX_PTP_CLIENT_ANNOUNCE_RECEIPT_TIMEOUT 3
91 #endif
92 
93 
94 /* Define the time interval between successive Announce packet, expressed as log 2.
95    This value should be uniform throughout a domain. The default value is 1=2s. */
96 
97 #ifndef NX_PTP_CLIENT_LOG_ANNOUNCE_INTERVAL
98 #define NX_PTP_CLIENT_LOG_ANNOUNCE_INTERVAL    1
99 #endif
100 
101 
102 /* Define the interval for sending Delay request packets */
103 
104 #ifndef NX_PTP_CLIENT_DELAY_REQ_INTERVAL
105 #define NX_PTP_CLIENT_DELAY_REQ_INTERVAL       (2 * NX_PTP_CLIENT_TIMER_TICKS_PER_SECOND)
106 #endif
107 
108 
109 /* Set maximum queue depth for client socket.*/
110 
111 #ifndef NX_PTP_CLIENT_MAX_QUEUE_DEPTH
112 #define NX_PTP_CLIENT_MAX_QUEUE_DEPTH          5
113 #endif
114 
115 /* Define the maximum size of a PTP message */
116 
117 #define NX_PTP_CLIENT_PACKET_DATA_SIZE         64
118 
119 /* Define Announce receipt timeout expire value */
120 #define NX_PTP_CLIENT_ANNOUNCE_EXPIRATION      (NX_PTP_CLIENT_ANNOUNCE_RECEIPT_TIMEOUT * \
121                                                 (1 << NX_PTP_CLIENT_LOG_ANNOUNCE_INTERVAL) * \
122                                                 NX_PTP_CLIENT_TIMER_TICKS_PER_SECOND)
123 
124 
125 /* Define a PTP Time */
126 
127 typedef struct NX_PTP_TIME_STRUCT
128 {
129     /* The MSB of the number of seconds */
130     LONG  second_high;
131 
132     /* The LSB of the number of seconds */
133     ULONG second_low;
134 
135     /* The number of nanoseconds */
136     LONG  nanosecond;
137 } NX_PTP_TIME;
138 
139 
140 /* Define the PTP Date Time structure.  */
141 
142 typedef struct NX_PTP_DATE_TIME_STRUCT
143 {
144     UINT  year;
145     UCHAR month;
146     UCHAR day;
147     UCHAR hour;
148     UCHAR minute;
149     UCHAR second;
150     UCHAR weekday;
151     ULONG nanosecond;
152 } NX_PTP_DATE_TIME;
153 
154 
155 /* Internal PTP error processing codes.  */
156 
157 #define NX_PTP_ERROR_CONSTANT                     0xD00
158 /* Client side errors.  */
159 #define NX_PTP_CLIENT_NOT_STARTED                 (NX_PTP_ERROR_CONSTANT | 0x01) /* PTP Client task is not running */
160 #define NX_PTP_CLIENT_ALREADY_STARTED             (NX_PTP_ERROR_CONSTANT | 0x02) /* PTP Client task is already running */
161 #define NX_PTP_PARAM_ERROR                        (NX_PTP_ERROR_CONSTANT | 0x03) /* Invalid non pointer parameter.  */
162 #define NX_PTP_CLIENT_INSUFFICIENT_PACKET_PAYLOAD (NX_PTP_ERROR_CONSTANT | 0x04) /* Client not properly initialized to receive time data.  */
163 #define NX_PTP_CLIENT_CLOCK_CALLBACK_FAILURE      (NX_PTP_ERROR_CONSTANT | 0x05) /* PTP clock callback returns error.  */
164 
165 
166 /* PTP Protocol Definitions */
167 
168 /* Define the size of the PTP Clock Identity field */
169 #define NX_PTP_CLOCK_IDENTITY_SIZE                8
170 
171 /* Define the size of the PTP Clock Port and Identity field */
172 #define NX_PTP_CLOCK_PORT_IDENTITY_SIZE           (NX_PTP_CLOCK_IDENTITY_SIZE + 2)
173 
174 
175 /* PTP event callback */
176 
177 struct NX_PTP_CLIENT_STRUCT;
178 
179 typedef UINT (*NX_PTP_CLIENT_EVENT_CALLBACK)(struct NX_PTP_CLIENT_STRUCT *client_ptr, UINT event,
180                                              VOID *event_data, VOID *callback_data);
181 
182 #define NX_PTP_CLIENT_EVENT_MASTER                0
183 #define NX_PTP_CLIENT_EVENT_SYNC                  1
184 #define NX_PTP_CLIENT_EVENT_TIMEOUT               2
185 
186 
187 /* PTP clock callback operations  */
188 
189 typedef UINT (*NX_PTP_CLIENT_CLOCK_CALLBACK)(struct NX_PTP_CLIENT_STRUCT *client_ptr, UINT operation,
190                                              NX_PTP_TIME *time_ptr, NX_PACKET *packet_ptr, VOID *callback_data);
191 
192 #define NX_PTP_CLIENT_CLOCK_INIT                  0     /* Initialization */
193 #define NX_PTP_CLIENT_CLOCK_SET                   1     /* Set the PTP clock */
194 #define NX_PTP_CLIENT_CLOCK_GET                   2     /* Get the PTP clock */
195 #define NX_PTP_CLIENT_CLOCK_ADJUST                3     /* Adjust the PTP clock */
196 #define NX_PTP_CLIENT_CLOCK_PACKET_TS_EXTRACT     4     /* Extract timestamp from packet */
197 #define NX_PTP_CLIENT_CLOCK_PACKET_TS_PREPARE     5     /* Prepare timestamp for packet */
198 #define NX_PTP_CLIENT_CLOCK_SOFT_TIMER_UPDATE     6     /* Update timer for soft implementation */
199 
200 
201 /* Master messages data */
202 typedef struct NX_PTP_CLIENT_MASTER_STRUCT
203 {
204     NXD_ADDRESS *nx_ptp_client_master_address;
205     UCHAR       *nx_ptp_client_master_port_identity;
206     UCHAR        nx_ptp_client_master_priority1;
207     UCHAR        nx_ptp_client_master_priority2;
208     UCHAR        nx_ptp_client_master_clock_class;
209     UCHAR        nx_ptp_client_master_clock_accuracy;
210     USHORT       nx_ptp_client_master_offset_scaled_log_variance;
211     UCHAR       *nx_ptp_client_master_grandmaster_identity;
212     USHORT       nx_ptp_client_master_steps_removed;
213     UCHAR        nx_ptp_client_master_time_source;
214 } NX_PTP_CLIENT_MASTER;
215 
216 /* Sync flags */
217 #define NX_PTP_CLIENT_SYNC_CALIBRATED     (1 << 0)
218 #define NX_PTP_CLIENT_SYNC_UTC_REASONABLE (1 << 1)
219 #define NX_PTP_CLIENT_SYNC_LEAP59         (1 << 2)
220 #define NX_PTP_CLIENT_SYNC_LEAP61         (1 << 3)
221 
222 /* Sync message data */
223 typedef struct NX_PTP_CLIENT_SYNC_STRUCT
224 {
225     USHORT nx_ptp_client_sync_flags;
226     SHORT  nx_ptp_client_sync_utc_offset;
227 } NX_PTP_CLIENT_SYNC;
228 
229 
230 /* Define the Type of messages */
231 
232 #define NX_PTP_CLIENT_ALL_EVENTS  0xFFFFFFFF /* all events of PTP client */
233 #define NX_PTP_CLIENT_STOP_EVENT  0x00000001 /* stop the PTP client */
234 #define NX_PTP_CLIENT_RX_EVENT    0x00000002 /* received UDP packet */
235 #define NX_PTP_CLIENT_TIMER_EVENT 0x00000004 /* timer tick */
236 
237 
238 /* Define the size of the PTP client message queue */
239 
240 #define NX_PTP_CLIENT_MESSAGE_QUEUE_SIZE   16
241 
242 
243 /* Define the state of the PTP Client thread */
244 
245 #define NX_PTP_CLIENT_THREAD_IDLE          0
246 #define NX_PTP_CLIENT_THREAD_RUNNING       1
247 #define NX_PTP_CLIENT_THREAD_STOPPING      2
248 #define NX_PTP_CLIENT_THREAD_STOPPED       3
249 
250 
251 /* Define the state of the PTP Client clock */
252 
253 #define NX_PTP_CLIENT_STATE_LISTENING      0
254 #define NX_PTP_CLIENT_STATE_WAIT_SYNC      1
255 #define NX_PTP_CLIENT_STATE_WAIT_FOLLOW_UP 2
256 
257 
258 /* Define the state of the delay measurement process */
259 
260 #define NX_PTP_CLIENT_DELAY_IDLE           0
261 #define NX_PTP_CLIENT_DELAY_WAIT_REQ_TS    1
262 #define NX_PTP_CLIENT_DELAY_WAIT_RESP      2
263 
264 
265 /* Define the structure of a PTP Client */
266 
267 typedef struct NX_PTP_CLIENT_STRUCT
268 {
269     /* PTP Client ID */
270     ULONG                        nx_ptp_client_id;
271 
272     /* Pointer to the Client IP instance.  */
273     NX_IP                       *nx_ptp_client_ip_ptr;
274 
275     /* Index to PTP network interface  */
276     UINT                         nx_ptp_client_interface_index;
277 
278     /* Pointer to the Client packet pool.  */
279     NX_PACKET_POOL              *nx_ptp_client_packet_pool_ptr;
280 
281     /* PTP Domain Number */
282     UCHAR                        nx_ptp_client_domain;
283 
284     /* PTP Transport Specific */
285     UCHAR                        nx_ptp_client_transport_specific;
286 
287     /* PTP Client Port and Identity */
288     UCHAR                        nx_ptp_client_port_identity[NX_PTP_CLOCK_PORT_IDENTITY_SIZE];
289 
290     /* PTP event handler callback */
291     NX_PTP_CLIENT_EVENT_CALLBACK nx_ptp_client_event_callback;
292     VOID                        *nx_ptp_client_event_callback_data;
293 
294     /* PTP clock callback */
295     NX_PTP_CLIENT_CLOCK_CALLBACK nx_ptp_client_clock_callback;
296     VOID                        *nx_ptp_client_clock_callback_data;
297 
298     /* PTP General Messages UDP Socket */
299     NX_UDP_SOCKET                nx_ptp_client_general_socket;
300 
301     /* PTP Event Messages UDP Socket */
302     NX_UDP_SOCKET                nx_ptp_client_event_socket;
303 
304     /* The message queue */
305     TX_EVENT_FLAGS_GROUP         nx_ptp_client_events;
306 
307     /* Set if IPv4 multicast group has been joined */
308     UCHAR                        nx_ptp_client_ipv4_group_joined;
309 
310 #if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6)
311     /* Set if IPv6 multicast group has been joined */
312     UCHAR                        nx_ptp_client_ipv6_group_joined;
313 #endif
314 
315     /* The software clock value */
316     NX_PTP_TIME                  nx_ptp_client_soft_clock;
317 
318     /* The state of the PTP client */
319     UCHAR                        nx_ptp_client_state;
320 
321     /* The state of the delay measurement */
322     UCHAR                        nx_ptp_client_delay_state;
323 
324     /* The current UTC offset flags */
325     USHORT                       nx_ptp_client_sync_flags;
326 
327     /* The current UTC offset */
328     SHORT                        nx_ptp_client_utc_offset;
329 
330     /* The address of the master clock */
331     NXD_ADDRESS                  nx_ptp_client_master_addr;
332 
333     /* The identity of the master clock */
334     UCHAR                        nx_ptp_client_master_port_identity[NX_PTP_CLOCK_PORT_IDENTITY_SIZE];
335 
336     /* The current sync master timestamp */
337     NX_PTP_TIME                  nx_ptp_client_sync;
338 
339     /* The current sync client timestamp */
340     NX_PTP_TIME                  nx_ptp_client_sync_ts;
341 
342     /* The id of the sync message */
343     USHORT                       nx_ptp_client_sync_id;
344 
345     /* The id of the last delay_req message */
346     USHORT                       nx_ptp_client_delay_req_id;
347 
348     /* The delay request interval timer */
349     INT                          nx_ptp_client_delay_req_timer;
350 
351     /* The Announce timeout */
352     INT                          nx_ptp_client_announce_timeout;
353 
354     /* The delay request flag */
355     UINT                         nx_ptp_client_delay_req_flag;
356 
357     /* The delay request client timestamp */
358     NX_PTP_TIME                  nx_ptp_client_delay_ts;
359 
360     /* The delay request packet pointer */
361     NX_PACKET                   *nx_ptp_client_delay_req_packet_ptr;
362 
363     /* The PTP client timer */
364     TX_TIMER                     nx_ptp_client_timer;
365 
366     /* The current state of the PTP Client thread */
367     UINT                         nx_ptp_client_thread_state;
368 
369     /* The PTP client processing thread */
370     TX_THREAD                    nx_ptp_client_thread;
371 } NX_PTP_CLIENT;
372 
373 
374 #ifndef NX_PTP_SOURCE_CODE
375 
376 /* Define the system API mappings based on the error checking selected by the user.   */
377 
378 /* Determine if error checking is desired.  If so, map API functions
379    to the appropriate error checking front-ends.  Otherwise, map API
380    functions to the core functions that actually perform the work.
381    Note: error checking is enabled by default.  */
382 
383 
384 #ifdef NX_PTP_DISABLE_ERROR_CHECKING
385 
386 /* Services without error checking.  */
387 
388 #define nx_ptp_client_create                       _nx_ptp_client_create
389 #define nx_ptp_client_delete                       _nx_ptp_client_delete
390 #define nx_ptp_client_start                        _nx_ptp_client_start
391 #define nx_ptp_client_stop                         _nx_ptp_client_stop
392 #define nx_ptp_client_time_get                     _nx_ptp_client_time_get
393 #define nx_ptp_client_time_set                     _nx_ptp_client_time_set
394 #define nx_ptp_client_master_info_get              _nx_ptp_client_master_info_get
395 #define nx_ptp_client_sync_info_get                _nx_ptp_client_sync_info_get
396 #define nx_ptp_client_packet_timestamp_notify      _nx_ptp_client_packet_timestamp_notify
397 #define nx_ptp_client_soft_clock_callback          _nx_ptp_client_soft_clock_callback
398 #define nx_ptp_client_utility_time_diff            _nx_ptp_client_utility_time_diff
399 #define nx_ptp_client_utility_convert_time_to_date _nx_ptp_client_utility_convert_time_to_date
400 
401 #else
402 
403 /* Services with error checking.  */
404 
405 #define nx_ptp_client_create                       _nxe_ptp_client_create
406 #define nx_ptp_client_delete                       _nxe_ptp_client_delete
407 #define nx_ptp_client_start                        _nxe_ptp_client_start
408 #define nx_ptp_client_stop                         _nxe_ptp_client_stop
409 #define nx_ptp_client_time_get                     _nxe_ptp_client_time_get
410 #define nx_ptp_client_time_set                     _nxe_ptp_client_time_set
411 #define nx_ptp_client_master_info_get              _nxe_ptp_client_master_info_get
412 #define nx_ptp_client_sync_info_get                _nxe_ptp_client_sync_info_get
413 #define nx_ptp_client_packet_timestamp_notify      _nx_ptp_client_packet_timestamp_notify
414 #define nx_ptp_client_soft_clock_callback          _nx_ptp_client_soft_clock_callback
415 #define nx_ptp_client_utility_time_diff            _nxe_ptp_client_utility_time_diff
416 #define nx_ptp_client_utility_convert_time_to_date _nxe_ptp_client_utility_convert_time_to_date
417 
418 #endif
419 
420 #endif
421 
422 
423 /* Define the function prototypes of the PTP Client API */
424 
425 UINT _nx_ptp_client_create(NX_PTP_CLIENT *client_ptr, NX_IP *ip_ptr, UINT interface_index,
426                            NX_PACKET_POOL *packet_pool_ptr, UINT thread_priority, UCHAR *thread_stack, UINT stack_size,
427                            NX_PTP_CLIENT_CLOCK_CALLBACK clock_callback, VOID *clock_callback_data);
428 UINT _nx_ptp_client_delete(NX_PTP_CLIENT *client_ptr);
429 UINT _nx_ptp_client_start(NX_PTP_CLIENT *client_ptr, UCHAR *client_port_identity_ptr, UINT client_port_identity_length,
430                           UINT domain, UINT transport_specific, NX_PTP_CLIENT_EVENT_CALLBACK event_callback,
431                           VOID *event_callback_data);
432 UINT _nx_ptp_client_stop(NX_PTP_CLIENT *client_ptr);
433 UINT _nx_ptp_client_time_get(NX_PTP_CLIENT *client_ptr, NX_PTP_TIME *time_ptr);
434 UINT _nx_ptp_client_time_set(NX_PTP_CLIENT *client_ptr, NX_PTP_TIME *time_ptr);
435 UINT _nx_ptp_client_master_info_get(NX_PTP_CLIENT_MASTER *master_ptr, NXD_ADDRESS *address, UCHAR **port_identity,
436                                     UINT *port_identity_length, UCHAR *priority1, UCHAR *priority2, UCHAR *clock_class,
437                                     UCHAR *clock_accuracy, USHORT *clock_variance, UCHAR **grandmaster_identity,
438                                     UINT *grandmaster_identity_length, USHORT *steps_removed, UCHAR *time_source);
439 UINT _nx_ptp_client_sync_info_get(NX_PTP_CLIENT_SYNC *sync_ptr, USHORT *flags, SHORT *utc_offset);
440 UINT _nx_ptp_client_utility_time_diff(NX_PTP_TIME *time1_ptr, NX_PTP_TIME *time2_ptr, NX_PTP_TIME *result_ptr);
441 UINT _nx_ptp_client_utility_convert_time_to_date(NX_PTP_TIME *time_ptr, LONG offset, NX_PTP_DATE_TIME *date_time_ptr);
442 VOID _nx_ptp_client_packet_timestamp_notify(NX_PTP_CLIENT *client_ptr, NX_PACKET *packet_ptr, NX_PTP_TIME *timestamp_ptr);
443 UINT _nx_ptp_client_soft_clock_callback(NX_PTP_CLIENT *client_ptr, UINT operation,
444                                         NX_PTP_TIME *time_ptr, NX_PACKET *packet_ptr,
445                                         VOID *callback_data);
446 
447 UINT _nxe_ptp_client_create(NX_PTP_CLIENT *client_ptr, NX_IP *ip_ptr, UINT interface_index,
448                             NX_PACKET_POOL *packet_pool_ptr, UINT thread_priority, UCHAR *thread_stack, UINT stack_size,
449                             NX_PTP_CLIENT_CLOCK_CALLBACK clock_callback, VOID *clock_callback_data);
450 UINT _nxe_ptp_client_delete(NX_PTP_CLIENT *client_ptr);
451 UINT _nxe_ptp_client_start(NX_PTP_CLIENT *client_ptr, UCHAR *client_port_identity_ptr, UINT client_port_identity_length,
452                            UINT domain, UINT transport_specific, NX_PTP_CLIENT_EVENT_CALLBACK event_callback,
453                            VOID *event_callback_data);
454 UINT _nxe_ptp_client_stop(NX_PTP_CLIENT *client_ptr);
455 UINT _nxe_ptp_client_time_get(NX_PTP_CLIENT *client_ptr, NX_PTP_TIME *time_ptr);
456 UINT _nxe_ptp_client_time_set(NX_PTP_CLIENT *client_ptr, NX_PTP_TIME *time_ptr);
457 UINT _nxe_ptp_client_master_info_get(NX_PTP_CLIENT_MASTER *master_ptr, NXD_ADDRESS *address, UCHAR **port_identity,
458                                      UINT *port_identity_length, UCHAR *priority1, UCHAR *priority2, UCHAR *clock_class,
459                                      UCHAR *clock_accuracy, USHORT *clock_variance, UCHAR **grandmaster_identity,
460                                      UINT *grandmaster_identity_length, USHORT *steps_removed, UCHAR *time_source);
461 UINT _nxe_ptp_client_sync_info_get(NX_PTP_CLIENT_SYNC *sync_ptr, USHORT *flags, SHORT *utc_offset);
462 UINT _nxe_ptp_client_utility_time_diff(NX_PTP_TIME *time1_ptr, NX_PTP_TIME *time2_ptr, NX_PTP_TIME *result_ptr);
463 UINT _nxe_ptp_client_utility_convert_time_to_date(NX_PTP_TIME *time_ptr, LONG offset, NX_PTP_DATE_TIME *date_time_ptr);
464 
465 
466 /* Define the function prototypes of the private utility functions */
467 
468 VOID _nx_ptp_client_utility_time_div_by_2(NX_PTP_TIME *time_ptr);
469 VOID _nx_ptp_client_utility_add64(LONG *a_hi, ULONG *a_lo, LONG b_hi, ULONG b_lo);
470 VOID _nx_ptp_client_utility_sub64(LONG *a_hi, ULONG *a_lo, LONG b_hi, ULONG b_lo);
471 VOID _nx_ptp_client_utility_inc64(LONG *a_hi, ULONG *a_lo);
472 VOID _nx_ptp_client_utility_dec64(LONG *a_hi, ULONG *a_lo);
473 VOID _nx_ptp_client_utility_neg64(LONG *a_hi, ULONG *a_lo);
474 
475 
476 /* Determine if a C++ compiler is being used.  If so, complete the standard
477    C conditional started above.  */
478 #ifdef __cplusplus
479 }
480 #endif
481 
482 #endif  /* NX_PTP_CLIENT_H */
483