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