1 /*
2  * Copyright (c) 2024 BayLibre SAS
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file clock.h
9  * @brief PTP Clock data structure and interface API
10  *
11  * References are to version 2019 of IEEE 1588, ("PTP")
12  */
13 
14 #ifndef ZEPHYR_INCLUDE_PTP_CLOCK_H_
15 #define ZEPHYR_INCLUDE_PTP_CLOCK_H_
16 
17 #include <zephyr/kernel.h>
18 
19 #include <zephyr/net/socket.h>
20 #include <zephyr/sys/slist.h>
21 
22 #include "ds.h"
23 #include "port.h"
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 /** @brief Threshold value for accepting PTP Instance for consideration in BTCA */
30 #define FOREIGN_TIME_TRANSMITTER_THRESHOLD 2
31 
32 /** @brief Multiplication factor of message intervals to create time window for announce messages */
33 #define FOREIGN_TIME_TRANSMITTER_TIME_WINDOW_MUL 4
34 
35 /* PTP Clock structure declaration. */
36 struct ptp_clock;
37 
38 /**
39  * @brief Types of PTP Clocks.
40  */
41 enum ptp_clock_type {
42 	PTP_CLOCK_TYPE_ORDINARY,
43 	PTP_CLOCK_TYPE_BOUNDARY,
44 	PTP_CLOCK_TYPE_P2P,
45 	PTP_CLOCK_TYPE_E2E,
46 	PTP_CLOCK_TYPE_MANAGEMENT,
47 };
48 
49 /**
50  * @brief PTP Clock time source.
51  */
52 enum ptp_time_src {
53 	PTP_TIME_SRC_ATOMIC_CLK = 0x10,
54 	PTP_TIME_SRC_GNSS = 0x20,
55 	PTP_TIME_SRC_TERRESTRIAL_RADIO = 0x30,
56 	PTP_TIME_SRC_SERIAL_TIME_CODE = 0x39,
57 	PTP_TIME_SRC_PTP = 0x40,
58 	PTP_TIME_SRC_NTP = 0x50,
59 	PTP_TIME_SRC_HAND_SET = 0x60,
60 	PTP_TIME_SRC_OTHER = 0x90,
61 	PTP_TIME_SRC_INTERNAL_OSC = 0xA0,
62 };
63 
64 /**
65  * @brief Foreign TimeTransmitter record.
66  */
67 struct ptp_foreign_tt_clock {
68 	/** @cond INTERNAL_HIDDEN */
69 	/** List object. */
70 	sys_snode_t	   node;
71 	/** @endcond */
72 	/** Foreign timeTransmitter's Port ID. */
73 	struct ptp_port_id port_id;
74 	/** List of messages received from Foreign timeTransmitter. */
75 	struct k_fifo	   messages;
76 	/** Number of messages received within a FOREIGN_TIME_TRANSMITTER_TIME_WINDOW. */
77 	uint16_t	   messages_count;
78 	/** Generic dataset of the Foreign timeTransmitter for BTCA. */
79 	struct ptp_dataset dataset;
80 	/** Pointer to the receiver. */
81 	struct ptp_port	   *port;
82 };
83 
84 /**
85  * @brief Function initializing PTP Clock instance.
86  *
87  * @return Pointer to the structure representing PTP Clock instance.
88  */
89 const struct ptp_clock *ptp_clock_init(void);
90 
91 /**
92  * @brief Function polling all sockets descriptors for incoming PTP messages.
93  *
94  * @return Pointer to the first element of array of socket descriptors assigned to PTP Ports.
95  */
96 struct zsock_pollfd *ptp_clock_poll_sockets(void);
97 
98 /**
99  * @brief Function handling STATE DECISION EVENT for the PTP Clock instance.
100  */
101 void ptp_clock_handle_state_decision_evt(void);
102 
103 /**
104  * @brief Function processing received PTP Management message at the PTP Clock level.
105  *
106  * @param[in] port PTP Port that received the message.
107  * @param[in] msg  Received PTP Management message.
108  *
109  * @return 1 if the message processing results in State Decision Event.
110  */
111 int ptp_clock_management_msg_process(struct ptp_port *port, struct ptp_msg *msg);
112 
113 /**
114  * @brief Function synchronizing local PTP Hardware Clock to the remote.
115  *
116  * @param[in] ingress Timestamp of the message reception from the remote node in nanoseconds.
117  * @param[in] egress  Timestamp of the message transmission to the local node in nanoseconds.
118  */
119 void ptp_clock_synchronize(uint64_t ingress, uint64_t egress);
120 
121 /**
122  * @brief Function updating PTP Clock path delay.
123  *
124  * @param[in] egress  Timestamp of the message transmission in nanoseconds.
125  * @param[in] ingress Timestamp of the message reception on the remote node in nanoseconds.
126  */
127 void ptp_clock_delay(uint64_t egress, uint64_t ingress);
128 /**
129  * @brief Function for getting list of PTP Ports for the PTP Clock instance.
130  *
131  * @return Pointer to the single-linked list of PTP Ports.
132  */
133 sys_slist_t *ptp_clock_ports_list(void);
134 
135 /**
136  * @brief Function returning PTP Clock type of the instance.
137  *
138  * @return PTP Clock type of the instance.
139  */
140 enum ptp_clock_type ptp_clock_type(void);
141 
142 /**
143  * @brief Function for getting PTP Clock Default dataset.
144  *
145  * @return Pointer to the structure representing PTP Clock instance's Default dataset.
146  */
147 const struct ptp_default_ds *ptp_clock_default_ds(void);
148 
149 /**
150  * @brief Function for getting PTP Clock Parent dataset.
151  *
152  * @return Pointer to the structure representing PTP Clock instance's Parent dataset.
153  */
154 const struct ptp_parent_ds *ptp_clock_parent_ds(void);
155 
156 /**
157  * @brief Function for getting PTP Clock Current dataset.
158  *
159  * @return Pointer to the structure representing PTP Clock instance's Current dataset.
160  */
161 const struct ptp_current_ds *ptp_clock_current_ds(void);
162 
163 /**
164  * @brief Function for getting PTP Clock Time Properties dataset.
165  *
166  * @return Pointer to the structure representing PTP Clock instance's Time Properties dataset.
167  */
168 const struct ptp_time_prop_ds *ptp_clock_time_prop_ds(void);
169 
170 /**
171  * @brief Function for getting a common dataset for the clock's default dataset.
172  *
173  * @return Pointer to the common dataset that contain data from ptp_default_ds structure.
174  */
175 const struct ptp_dataset *ptp_clock_ds(void);
176 
177 /**
178  * @brief Function for getting a common dataset for the clock's best foreign timeTransmitter clock.
179  *
180  * @return NULL if the clock doesn't have best foreign timeTransmitter clock or
181  * pointer to the ptp_dataset of the best foreign timeTransmitter clock.
182  */
183 const struct ptp_dataset *ptp_clock_best_foreign_ds(void);
184 
185 /**
186  * @brief Get PTP Port from network interface.
187  *
188  * @param[in] iface Pointer to the network interface.
189  *
190  * @return Pointer to the PTP Port binded with given interface. If no PTP Port assigned
191  * to the interface NULL is returned.
192  */
193 struct ptp_port *ptp_clock_port_from_iface(struct net_if *iface);
194 
195 /**
196  * @brief Function invalidating PTP Clock's array of file descriptors used for sockets.
197  */
198 void ptp_clock_pollfd_invalidate(void);
199 
200 /**
201  * @brief Function signalling timoeout of one of PTP Ports timer
202  * to the PTP Clock's file descriptor. The function should be called only from
203  * the context of timer expiration function.
204  */
205 void ptp_clock_signal_timeout(void);
206 
207 /**
208  * @brief Function signalling to the PTP Clock that STATE_DECISION_EVENT occurred and
209  * it needs to be handled.
210  */
211 void ptp_clock_state_decision_req(void);
212 
213 /**
214  * @brief Function adding PTP Port to the PTP Clock's list of initialized PTP Ports.
215  *
216  * @param[in] port Pointer to the PTP Port to be added to the PTP Clock's list.
217  */
218 void ptp_clock_port_add(struct ptp_port *port);
219 
220 /**
221  * @brief Function returning Pointer to the best PTP Clock's Foreign TimeTransmitter record.
222  *
223  * @return Pointer to the clock's best Foreign TimeTransmitter or
224  * NULL if there is no Foreign TimeTransmitter.
225  */
226 const struct ptp_foreign_tt_clock *ptp_clock_best_time_transmitter(void);
227 
228 /**
229  * @brief Function checking if given PTP Clock IDs are the same.
230  *
231  * @param[in] c1 Pointer to the PTP Clock ID.
232  * @param[in] c2 Pointer to the PTP Clock ID.
233  *
234  * @return True if the same, false otherwise.
235  */
236 bool ptp_clock_id_eq(const ptp_clk_id *c1, const ptp_clk_id *c2);
237 
238 #ifdef __cplusplus
239 }
240 #endif
241 
242 /**
243  * @}
244  */
245 
246 #endif /* ZEPHYR_INCLUDE_PTP_CLOCK_H_ */
247