| /* |
| * Copyright (c) 2024 BayLibre SAS |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /** |
| * @file tlv.h |
| * @brief Type, Length, Value extension for PTP |
| * |
| * References are to version 2019 of IEEE 1588, ("PTP") |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_PTP_TLV_H_ |
| #define ZEPHYR_INCLUDE_PTP_TLV_H_ |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #include <stdint.h> |
| |
| #include "ddt.h" |
| #include "msg.h" |
| |
| /** |
| * @brief Type of TLV (type, length, value) |
| * |
| * @note based on IEEE 1588-2019 Section 14.1.1 Table 52 |
| */ |
| enum ptp_tlv_type { |
| PTP_TLV_TYPE_MANAGEMENT = 1, |
| PTP_TLV_TYPE_MANAGEMENT_ERROR_STATUS, |
| PTP_TLV_TYPE_ORGANIZATION_EXTENSION, |
| PTP_TLV_TYPE_REQUEST_UNICAST_TRANSMISSION, |
| PTP_TLV_TYPE_GRANT_UNICAST_TRANSMISSION, |
| PTP_TLV_TYPE_CANCEL_UNICAST_TRANSMISSION, |
| PTP_TLV_TYPE_ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION, |
| PTP_TLV_TYPE_PATH_TRACE, |
| PTP_TLV_TYPE_ORGANIZATION_EXTENSION_PROPAGATE = 0x4000, |
| PTP_TLV_TYPE_ENHANCED_ACCURACY_METRICS, |
| PTP_TLV_TYPE_ORGANIZATION_EXTENSION_DO_NOT_PROPAGATE = 0x8000, |
| PTP_TLV_TYPE_L1_SYNC, |
| PTP_TLV_TYPE_PORT_COMMUNICATION_AVAILABILITY, |
| PTP_TLV_TYPE_PROTOCOL_ADDRESS, |
| PTP_TLV_TYPE_TIME_RECEIVER_RX_SYNC_TIMING_DATA, |
| PTP_TLV_TYPE_TIME_RECEIVER_RX_SYNC_COMPUTED_DATA, |
| PTP_TLV_TYPE_TIME_RECEIVER_TX_EVENT_TIMESTAMPS, |
| PTP_TLV_TYPE_CUMULATIVE_RATE_RATIO, |
| PTP_TLV_TYPE_PAD, |
| PTP_TLV_TYPE_AUTHENTICATION, |
| }; |
| |
| /** |
| * @brief PTP management message action field |
| * |
| * @note based on IEEE 1588-2019 Section 15.4.1.6 Table 57 |
| */ |
| enum ptp_mgmt_op { |
| PTP_MGMT_GET, |
| PTP_MGMT_SET, |
| PTP_MGMT_RESP, |
| PTP_MGMT_CMD, |
| PTP_MGMT_ACK, |
| }; |
| |
| /** |
| * @brief PTP management message ID |
| * |
| * @note based on IEEE 1588-2019 Section 15.5.2.3 Table 59 |
| */ |
| enum ptp_mgmt_id { |
| PTP_MGMT_NULL_PTP_MANAGEMENT = 0x0, |
| PTP_MGMT_CLOCK_DESCRIPTION, |
| PTP_MGMT_USER_DESCRIPTION, |
| PTP_MGMT_SAVE_IN_NON_VOLATILE_STORAGE, |
| PTP_MGMT_RESET_NON_VOLATILE_STORAGE, |
| PTP_MGMT_INITIALIZE, |
| PTP_MGMT_FAULT_LOG, |
| PTP_MGMT_FAULT_LOG_RESET, |
| PTP_MGMT_DEFAULT_DATA_SET = 0x2000, |
| PTP_MGMT_CURRENT_DATA_SET, |
| PTP_MGMT_PARENT_DATA_SET, |
| PTP_MGMT_TIME_PROPERTIES_DATA_SET, |
| PTP_MGMT_PORT_DATA_SET, |
| PTP_MGMT_PRIORITY1, |
| PTP_MGMT_PRIORITY2, |
| PTP_MGMT_DOMAIN, |
| PTP_MGMT_TIME_RECEIVER_ONLY, |
| PTP_MGMT_LOG_ANNOUNCE_INTERVAL, |
| PTP_MGMT_ANNOUNCE_RECEIPT_TIMEOUT, |
| PTP_MGMT_LOG_SYNC_INTERVAL, |
| PTP_MGMT_VERSION_NUMBER, |
| PTP_MGMT_ENABLE_PORT, |
| PTP_MGMT_DISABLE_PORT, |
| PTP_MGMT_TIME, |
| PTP_MGMT_CLOCK_ACCURACY, |
| PTP_MGMT_UTC_PROPERTIES, |
| PTP_MGMT_TRACEBILITY_PROPERTIES, |
| PTP_MGMT_TIMESCALE_PROPERTIES, |
| PTP_MGMT_UNICAST_NEGOTIATION_ENABLE, |
| PTP_MGMT_PATH_TRACE_LIST, |
| PTP_MGMT_PATH_TRACE_ENABLE, |
| PTP_MGMT_GRANDMASTER_CLUSTER_TABLE, |
| PTP_MGMT_UNICAST_TIME_TRANSMITTER_TABLE, |
| PTP_MGMT_UNICAST_TIME_TRANSMITTER_MAX_TABLE_SIZE, |
| PTP_MGMT_ACCEPTABLE_TIME_TRANSMITTER_TABLE, |
| PTP_MGMT_ACCEPTABLE_TIME_TRANSMITTER_TABLE_ENABLED, |
| PTP_MGMT_ACCEPTABLE_TIME_TRANSMITTER_MAX_TABLE_SIZE, |
| PTP_MGMT_ALTERNATE_TIME_TRANSMITTER, |
| PTP_MGMT_ALTERNATE_TIME_OFFSET_ENABLE, |
| PTP_MGMT_ALTERNATE_TIME_OFFSET_NAME, |
| PTP_MGMT_ALTERNATE_TIME_OFFSET_MAX_KEY, |
| PTP_MGMT_ALTERNATE_TIME_OFFSET_PROPERTIES, |
| PTP_MGMT_EXTERNAL_PORT_CONFIGURATION_ENABLED = 0x3000, |
| PTP_MGMT_TIME_TRANSMITTER_ONLY, |
| PTP_MGMT_HOLDOVER_UPGRADE_ENABLE, |
| PTP_MGMT_EXT_PORT_CONFIG_PORT_DATA_SET, |
| PTP_MGMT_TRANSPARENT_CLOCK_DEFAULT_DATA_SET = 0x4000, |
| PTP_MGMT_TRANSPARENT_CLOCK_PORT_DATA_SET, |
| PTP_MGMT_PRIMARY_DOMAIN, |
| PTP_MGMT_DELAY_MECHANISM = 0x6000, |
| PTP_MGMT_LOG_MIN_PDELAY_REQ_INTERVAL, |
| }; |
| |
| /** |
| * @brief Management error ID |
| * |
| * @note based on IEEE 1588-2019 Section 15.5.4.4 Table 109 |
| */ |
| enum ptp_mgmt_err { |
| PTP_MGMT_ERR_RESPONSE_TOO_BIG = 0x1, |
| PTP_MGMT_ERR_NO_SUCH_ID, |
| PTP_MGMT_ERR_WRONG_LENGTH, |
| PTP_MGMT_ERR_WRONG_VALUE, |
| PTP_MGMT_ERR_NOT_SETABLE, |
| PTP_MGMT_ERR_NOT_SUPPORTED, |
| PTP_MGMT_ERR_UNPOPULATED, |
| PTP_MGMT_ERR_GENERAL = 0xFFFE, |
| }; |
| |
| /** |
| * @brief PAD TLV - used to increase length of any PTP message. |
| * |
| * @note 14.4.2 - PAD TLV |
| */ |
| struct ptp_tlv_pad { |
| /** Identify type of TLV. */ |
| uint16_t type; |
| /** Length of pad. */ |
| uint16_t length; |
| /** Pad. */ |
| uint8_t pad[]; |
| } __packed; |
| |
| /** |
| * @brief Management TLV. |
| * |
| * @note 15.5.2 - MANAGEMENT TLV field format. |
| */ |
| struct ptp_tlv_mgmt { |
| uint16_t type; |
| uint16_t length; |
| uint16_t id; |
| uint8_t data[]; |
| } __packed; |
| |
| /** |
| * @brief Management error status TLV. |
| * |
| * @note 15.5.4 - MANAGEMENT_ERROR_STATUS TLV format. |
| */ |
| struct ptp_tlv_mgmt_err { |
| /** Type of TLV, shall be MANAGEMENT_ERROR_STATUS. */ |
| uint16_t type; |
| /** Length of following part of TLV. */ |
| uint16_t length; |
| /** Management error ID*/ |
| uint16_t err_id; |
| /** Management ID corresponding to the ID of management TLV that caused an error. */ |
| uint16_t id; |
| /** @cond INTERNAL_HIDEN */ |
| /** Padding. */ |
| uint32_t reserved; |
| /** @endcond */ |
| /** Optional text field to provide human-readable explanation of the error. */ |
| struct ptp_text display_data; |
| } __packed; |
| |
| /** |
| * @brief Structure holding pointers for Clock description send over TLV |
| */ |
| struct ptp_tlv_mgmt_clock_desc { |
| /** Type of PTP Clock. */ |
| uint16_t *type; |
| /** Physical Layer Protocol. */ |
| struct ptp_text *phy_protocol; |
| /** Number of bytes in phy_addr field. */ |
| uint16_t *phy_addr_len; |
| /** Physical address of the PTP Port. */ |
| uint8_t *phy_addr; |
| /** Protocol address of the PTP Port. */ |
| struct ptp_port_addr *protocol_addr; |
| /** Unique identifier of the manufacturer. */ |
| uint8_t *manufacturer_id; |
| /** Description of the PTP Instance from manufacturer. */ |
| struct ptp_text *product_desc; |
| /** Revision for components of the PTP Instance. */ |
| struct ptp_text *revision_data; |
| /** User defined description. */ |
| struct ptp_text *user_desc; |
| /** PTP Profile implemented by the PTP Port. */ |
| uint8_t *profile_id; |
| }; |
| |
| /** |
| * @brief Structure holding TLV. It is used as a helper to retrieve TLVs from PTP messages. |
| */ |
| struct ptp_tlv_container { |
| /** Object list. */ |
| sys_snode_t node; |
| /** Pointer to the TLV. */ |
| struct ptp_tlv *tlv; |
| /** Structure holding pointers for Clock description. */ |
| struct ptp_tlv_mgmt_clock_desc clock_desc; |
| }; |
| |
| /** |
| * @brief TLV data fields representing defaultDS dataset. |
| */ |
| struct ptp_tlv_default_ds { |
| /** Value of two-step flag and @ref ptp_default_ds.time_receiver_only of the dataset. */ |
| uint8_t flags; |
| /** @cond INTERNAL_HIDEN */ |
| /** Padding. */ |
| uint8_t reserved1; |
| /** @endcond */ |
| /** Value of @ref ptp_default_ds.n_ports of the dataset. */ |
| uint16_t n_ports; |
| /** Value of @ref ptp_default_ds.priority1 of the dataset. */ |
| uint8_t priority1; |
| /** Value of @ref ptp_default_ds.clk_quality of the dataset. */ |
| struct ptp_clk_quality clk_quality; |
| /** Value of @ref ptp_default_ds.priority2 of the dataset. */ |
| uint8_t priority2; |
| /** Value of @ref ptp_default_ds.clk_id of the dataset. */ |
| ptp_clk_id clk_id; |
| /** Value of @ref ptp_default_ds.domain of the dataset. */ |
| uint8_t domain; |
| /** @cond INTERNAL_HIDEN */ |
| /** Padding. */ |
| uint8_t reserved2; |
| /** @endcond */ |
| } __packed; |
| |
| /** |
| * @bref TLV data fields representing currentDS dataset. |
| */ |
| struct ptp_tlv_current_ds { |
| /** Value of @ref ptp_current_ds.steps_rm of the dataset. */ |
| uint16_t steps_rm; |
| /** Value of @ref ptp_current_ds.offset_from_tt of the dataset. */ |
| ptp_timeinterval offset_from_tt; |
| /** Value of @ref ptp_current_ds.mean_delay of the dataset. */ |
| ptp_timeinterval mean_delay; |
| } __packed; |
| |
| /** |
| * @brief TLV data fields representing parentDS dataset. |
| */ |
| struct ptp_tlv_parent_ds { |
| /** Value of @ref ptp_parent_ds.port_id of the dataset. */ |
| struct ptp_port_id port_id; |
| /** Value of @ref ptp_parent_ds.stats of the dataset. */ |
| uint8_t flags; |
| /** @cond INTERNAL_HIDEN */ |
| /** Padding. */ |
| uint8_t reserved; |
| /** @endcond */ |
| /** Value of @ref ptp_parent_ds.obsreved_parent_offset_scaled_log_variance |
| * of the dataset. |
| */ |
| uint16_t obsreved_parent_offset_scaled_log_variance; |
| /** Value of @ref ptp_parent_ds.obsreved_parent_clk_phase_change_rate of the dataset. */ |
| int32_t obsreved_parent_clk_phase_change_rate; |
| /** Value of @ref ptp_parent_ds.gm_priority1 of the dataset. */ |
| uint8_t gm_priority1; |
| /** Value of @ref ptp_parent_ds.gm_clk_quality of the dataset. */ |
| struct ptp_clk_quality gm_clk_quality; |
| /** Value of @ref ptp_parent_ds.gm_priority2 of the dataset. */ |
| uint8_t gm_priority2; |
| /** Value of @ref ptp_parent_ds.gm_id of the dataset. */ |
| ptp_clk_id gm_id; |
| } __packed; |
| |
| /** |
| * @brief TLV data fields representing time_propertiesDS dataset. |
| */ |
| struct ptp_tlv_time_prop_ds { |
| /** Value of @ref ptp_time_prop_ds.current_utc_offset of the dataset. */ |
| int16_t current_utc_offset; |
| /** Value of @ref ptp_time_prop_ds.flags of the dataset. */ |
| uint8_t flags; |
| /** Value of @ref ptp_time_prop_ds.time_src of the dataset. */ |
| uint8_t time_src; |
| } __packed; |
| |
| /** |
| * @brief TLV data fields representing portDS dataset. |
| */ |
| struct ptp_tlv_port_ds { |
| /** Value of @ref ptp_port_ds.id of the dataset. */ |
| struct ptp_port_id id; |
| /** Value of @ref ptp_port_ds.state of the dataset. */ |
| uint8_t state; |
| /** Value of @ref ptp_port_ds.log_min_delay_req_interval of the dataset. */ |
| int8_t log_min_delay_req_interval; |
| /** Value of @ref ptp_port_ds.mean_link_delay of the dataset. */ |
| ptp_timeinterval mean_link_delay; |
| /** Value of @ref ptp_port_ds.log_announce_interval of the dataset. */ |
| int8_t log_announce_interval; |
| /** Value of @ref ptp_port_ds.announce_receipt_timeout of the dataset. */ |
| uint8_t announce_receipt_timeout; |
| /** Value of @ref ptp_port_ds.log_sync_interval of the dataset. */ |
| int8_t log_sync_interval; |
| /** Value of @ref ptp_port_ds.delay_mechanism of the dataset. */ |
| uint8_t delay_mechanism; |
| /** Value of @ref ptp_port_ds.log_min_pdelay_req_interval of the dataset. */ |
| int8_t log_min_pdelay_req_interval; |
| /** Value of @ref ptp_port_ds.version of the dataset. */ |
| uint8_t version; |
| } __packed; |
| |
| /** |
| * @brief Function allocating memory for TLV container structure. |
| * |
| * @return Pointer to the TLV container structure. |
| */ |
| struct ptp_tlv_container *ptp_tlv_alloc(void); |
| |
| /** |
| * @brief Function freeing memory used by TLV container. |
| * |
| * @param[in] tlv_container Pointer to the TLV container structure. |
| */ |
| void ptp_tlv_free(struct ptp_tlv_container *tlv_container); |
| |
| /** |
| * @brief Function for getting type of action to be taken on receipt of the PTP message. |
| * |
| * @param[in] msg Pointer to the PTP message. |
| * |
| * @return Type of action to be taken. |
| */ |
| enum ptp_mgmt_op ptp_mgmt_action(struct ptp_msg *msg); |
| |
| /** |
| * @brief Function for getting type of the TLV. |
| * |
| * @param[in] tlv Pointer to the TLV. |
| * |
| * @return Type of TLV message. |
| */ |
| enum ptp_tlv_type ptp_tlv_type(struct ptp_tlv *tlv); |
| |
| /** |
| * @brief Function processing TLV after reception, and before processing by PTP stack. |
| * |
| * @param[in] tlv Pointer to the received TLV. |
| * |
| * @return Zero on success, otherwise negative. |
| */ |
| int ptp_tlv_post_recv(struct ptp_tlv *tlv); |
| |
| /** |
| * @brief Function preparing TLV to on-wire format before transmitting. |
| * |
| * @param[in] tlv Pointer to the received TLV. |
| */ |
| void ptp_tlv_pre_send(struct ptp_tlv *tlv); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* ZEPHYR_INCLUDE_PTP_TLV_H_ */ |