2011-11-05 02:20:23 +08:00
|
|
|
/**
|
|
|
|
* @file port.h
|
|
|
|
* @note Copyright (C) 2011 Richard Cochran <richardcochran@gmail.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
#ifndef HAVE_PORT_H
|
|
|
|
#define HAVE_PORT_H
|
|
|
|
|
2012-04-05 17:54:41 +08:00
|
|
|
#include "dm.h"
|
2011-11-13 01:44:55 +08:00
|
|
|
#include "fd.h"
|
|
|
|
#include "foreign.h"
|
|
|
|
#include "fsm.h"
|
2014-05-07 00:41:48 +08:00
|
|
|
#include "notification.h"
|
2011-11-13 01:44:55 +08:00
|
|
|
#include "transport.h"
|
|
|
|
|
2012-08-21 01:56:18 +08:00
|
|
|
/* forward declarations */
|
|
|
|
struct interface;
|
|
|
|
struct clock;
|
2012-08-02 12:29:03 +08:00
|
|
|
|
2011-11-05 02:20:23 +08:00
|
|
|
/** Opaque type. */
|
|
|
|
struct port;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the dataset from a port's best foreign clock record, if any
|
2011-11-13 01:44:55 +08:00
|
|
|
* has yet been discovered. This function does not bring the returned
|
|
|
|
* dataset up to date, so the caller should invoke port_compute_best()
|
|
|
|
* beforehand.
|
2011-11-05 02:20:23 +08:00
|
|
|
*
|
2011-11-13 01:44:55 +08:00
|
|
|
* @param port A pointer previously obtained via port_open().
|
2011-11-05 02:20:23 +08:00
|
|
|
* @return A pointer to a dataset, or NULL.
|
|
|
|
*/
|
|
|
|
struct dataset *port_best_foreign(struct port *port);
|
|
|
|
|
2011-11-13 01:44:55 +08:00
|
|
|
/**
|
|
|
|
* Close a port and free its associated resources. After this call
|
|
|
|
* returns, @a port is no longer a valid port instance.
|
|
|
|
*
|
|
|
|
* @param port A pointer previously obtained via port_open().
|
|
|
|
*/
|
|
|
|
void port_close(struct port *port);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Computes the 'best' foreign master discovered on a port. This has
|
|
|
|
* the side effect of updating the 'dataset' field of the returned
|
|
|
|
* foreign master.
|
|
|
|
*
|
|
|
|
* @param port A pointer previously obtained via port_open().
|
|
|
|
* @return A pointer to the port's best foreign master, or NULL.
|
|
|
|
*/
|
|
|
|
struct foreign_clock *port_compute_best(struct port *port);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dispatch a port event. This may cause a state transition on the
|
|
|
|
* port, with the associated side effect.
|
|
|
|
*
|
|
|
|
* @param port A pointer previously obtained via port_open().
|
|
|
|
* @param event One of the @a fsm_event codes.
|
2012-01-07 04:12:50 +08:00
|
|
|
* @param mdiff Whether a new master has been selected.
|
2011-11-13 01:44:55 +08:00
|
|
|
*/
|
2017-02-06 01:25:18 +08:00
|
|
|
void port_dispatch(struct port *p, enum fsm_event event, int mdiff);
|
2011-11-13 01:44:55 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Generates state machine events based on activity on a port's file
|
|
|
|
* descriptors.
|
|
|
|
*
|
|
|
|
* @param port A pointer previously obtained via port_open().
|
|
|
|
* @param fd_index The index of the active file descriptor.
|
|
|
|
* @return One of the @a fsm_event codes.
|
|
|
|
*/
|
|
|
|
enum fsm_event port_event(struct port *port, int fd_index);
|
|
|
|
|
2012-07-29 20:31:30 +08:00
|
|
|
/**
|
|
|
|
* Forward a message on a given port.
|
|
|
|
* @param port A pointer previously obtained via port_open().
|
|
|
|
* @param msg The message to send. Must be in network byte order.
|
|
|
|
* @return Zero on success, non-zero otherwise.
|
|
|
|
*/
|
2014-05-02 18:37:46 +08:00
|
|
|
int port_forward(struct port *p, struct ptp_message *msg);
|
2012-07-29 20:31:30 +08:00
|
|
|
|
2014-05-02 18:37:47 +08:00
|
|
|
/**
|
|
|
|
* Forward a message on a given port to the address stored in the message.
|
|
|
|
* @param port A pointer previously obtained via port_open().
|
|
|
|
* @param msg The message to send. Must be in network byte order.
|
|
|
|
* @return Zero on success, non-zero otherwise.
|
|
|
|
*/
|
|
|
|
int port_forward_to(struct port *p, struct ptp_message *msg);
|
|
|
|
|
2014-03-24 16:53:19 +08:00
|
|
|
/**
|
|
|
|
* Prepare message for transmission and send it to a given port. Note that
|
|
|
|
* a single message cannot be sent several times using this function, that
|
|
|
|
* would lead to corrupted data being sent. Use msg_pre_send and
|
|
|
|
* port_forward if you need to send single message to several ports.
|
|
|
|
* @param p A pointer previously obtained via port_open().
|
|
|
|
* @param msg The message to send.
|
2018-03-17 14:35:09 +08:00
|
|
|
* @param event One of the @ref transport_event enumeration values.
|
2014-03-24 16:53:19 +08:00
|
|
|
*/
|
2018-03-17 14:35:09 +08:00
|
|
|
int port_prepare_and_send(struct port *p, struct ptp_message *msg,
|
|
|
|
enum transport_event event);
|
2014-03-24 16:53:19 +08:00
|
|
|
|
2012-08-25 22:15:34 +08:00
|
|
|
/**
|
|
|
|
* Obtain a port's identity.
|
|
|
|
* @param p A pointer previously obtained via port_open().
|
|
|
|
* @return The port identity of 'p'.
|
|
|
|
*/
|
|
|
|
struct PortIdentity port_identity(struct port *p);
|
|
|
|
|
2014-08-14 21:56:03 +08:00
|
|
|
/**
|
|
|
|
* Obtain a port number.
|
|
|
|
* @param p A port instance.
|
|
|
|
* @return The port number of 'p'.
|
|
|
|
*/
|
|
|
|
int port_number(struct port *p);
|
|
|
|
|
2016-07-30 21:03:48 +08:00
|
|
|
/**
|
|
|
|
* Obtain the link status of a port.
|
|
|
|
* @param p A port instance.
|
|
|
|
* @return One (1) if the link is up, zero otherwise.
|
|
|
|
*/
|
|
|
|
int port_link_status_get(struct port *p);
|
|
|
|
|
2012-07-29 20:31:30 +08:00
|
|
|
/**
|
|
|
|
* Manage a port according to a given message.
|
|
|
|
* @param p A pointer previously obtained via port_open().
|
|
|
|
* @param ingress The port on which 'msg' was received.
|
|
|
|
* @param msg A management message.
|
2014-05-02 18:37:45 +08:00
|
|
|
* @return 1 if the message was responded to, 0 if it did not apply
|
|
|
|
* to the port, -1 if it was invalid.
|
2012-07-29 20:31:30 +08:00
|
|
|
*/
|
|
|
|
int port_manage(struct port *p, struct port *ingress, struct ptp_message *msg);
|
|
|
|
|
2012-08-02 12:36:07 +08:00
|
|
|
/**
|
|
|
|
* Send a management error status message.
|
|
|
|
* @param pid The id of the responding port.
|
|
|
|
* @param ingress Port on which the 'req' was received.
|
|
|
|
* @param req The management message which triggered the error.
|
|
|
|
* @param error_id One of the management error ID values.
|
|
|
|
* @return Zero on success, non-zero otherwise.
|
|
|
|
*/
|
2013-02-05 02:05:36 +08:00
|
|
|
int port_management_error(struct PortIdentity pid, struct port *ingress,
|
|
|
|
struct ptp_message *req, Enumeration16 error_id);
|
2012-08-02 12:36:07 +08:00
|
|
|
|
2012-08-02 12:33:32 +08:00
|
|
|
/**
|
|
|
|
* Allocate a reply to a management message.
|
|
|
|
*
|
|
|
|
* Messages are reference counted, and newly allocated messages have a
|
|
|
|
* reference count of one. Allocated messages are freed using the
|
|
|
|
* function @ref msg_put().
|
|
|
|
*
|
|
|
|
* @param pid The id of the responding port.
|
|
|
|
* @param ingress The port on which 'req' was received.
|
|
|
|
* @param req A management message.
|
|
|
|
* @return Pointer to a message on success, NULL otherwise.
|
|
|
|
*/
|
|
|
|
struct ptp_message *port_management_reply(struct PortIdentity pid,
|
|
|
|
struct port *ingress,
|
|
|
|
struct ptp_message *req);
|
|
|
|
|
2014-05-07 00:41:49 +08:00
|
|
|
/**
|
|
|
|
* Allocate a standalone reply management message.
|
|
|
|
*
|
|
|
|
* See note in @ref port_management_reply description about freeing the
|
|
|
|
* message. Also note that the constructed message does not have
|
|
|
|
* targetPortIdentity and sequenceId filled.
|
|
|
|
*
|
|
|
|
* @param pid The id of the responding port.
|
|
|
|
* @param port The port to which the message will be sent.
|
|
|
|
* @return Pointer to a message on success, NULL otherwise.
|
|
|
|
*/
|
|
|
|
struct ptp_message *port_management_notify(struct PortIdentity pid,
|
|
|
|
struct port *port);
|
|
|
|
|
2014-05-07 00:41:48 +08:00
|
|
|
/**
|
|
|
|
* Construct and send notification to subscribers about an event that
|
|
|
|
* occured on the port.
|
|
|
|
* @param p The port.
|
|
|
|
* @param event The identification of the event.
|
|
|
|
*/
|
|
|
|
void port_notify_event(struct port *p, enum notification event);
|
|
|
|
|
2011-11-13 01:44:55 +08:00
|
|
|
/**
|
|
|
|
* Open a network port.
|
2019-05-31 22:25:45 +08:00
|
|
|
* @param phc_device The name of PHC device as found on the command line.
|
2012-05-10 02:46:16 +08:00
|
|
|
* @param phc_index The PHC device index for the network device.
|
2012-08-21 01:56:18 +08:00
|
|
|
* @param timestamping The timestamping mode for this port.
|
|
|
|
* @param number An arbitrary number assigned to this port.
|
|
|
|
* @param interface The interface data
|
2011-11-13 01:44:55 +08:00
|
|
|
* @param clock A pointer to the system PTP clock.
|
|
|
|
* @return A pointer to an open port on success, or NULL otherwise.
|
|
|
|
*/
|
2019-05-31 22:25:45 +08:00
|
|
|
struct port *port_open(const char *phc_device,
|
|
|
|
int phc_index,
|
2011-11-13 01:44:55 +08:00
|
|
|
enum timestamp_type timestamping,
|
|
|
|
int number,
|
2012-08-21 01:56:18 +08:00
|
|
|
struct interface *interface,
|
2011-11-13 01:44:55 +08:00
|
|
|
struct clock *clock);
|
|
|
|
|
2011-11-05 02:20:23 +08:00
|
|
|
/**
|
|
|
|
* Returns a port's current state.
|
|
|
|
* @param port A port instance.
|
|
|
|
* @return One of the @ref port_state values.
|
|
|
|
*/
|
|
|
|
enum port_state port_state(struct port *port);
|
|
|
|
|
2017-08-07 02:43:30 +08:00
|
|
|
/**
|
|
|
|
* Update a port's current state based on a given event.
|
|
|
|
* @param p A pointer previously obtained via port_open().
|
|
|
|
* @param event One of the @a fsm_event codes.
|
|
|
|
* @param mdiff Whether a new master has been selected.
|
|
|
|
* @return One (1) if the port state has changed, zero otherwise.
|
|
|
|
*/
|
|
|
|
int port_state_update(struct port *p, enum fsm_event event, int mdiff);
|
|
|
|
|
2014-08-14 21:56:03 +08:00
|
|
|
/**
|
|
|
|
* Return array of file descriptors for this port. The fault fd is not
|
|
|
|
* included.
|
|
|
|
* @param port A port instance
|
|
|
|
* @return Array of file descriptors. Unused descriptors are guranteed
|
|
|
|
* to be set to -1.
|
|
|
|
*/
|
|
|
|
struct fdarray *port_fda(struct port *port);
|
|
|
|
|
2014-08-14 21:56:01 +08:00
|
|
|
/**
|
|
|
|
* Return file descriptor of the port.
|
|
|
|
* @param port A port instance.
|
|
|
|
* @return File descriptor or -1 if not applicable.
|
|
|
|
*/
|
|
|
|
int port_fault_fd(struct port *port);
|
|
|
|
|
2013-01-30 23:28:54 +08:00
|
|
|
/**
|
|
|
|
* Utility function for setting or resetting a file descriptor timer.
|
|
|
|
*
|
|
|
|
* This function sets the timer 'fd' to the value M(2^N), where M is
|
|
|
|
* the value of the 'scale' parameter and N in the value of the
|
|
|
|
* 'log_seconds' parameter.
|
|
|
|
*
|
|
|
|
* Passing both 'scale' and 'log_seconds' as zero disables the timer.
|
|
|
|
*
|
|
|
|
* @param fd A file descriptor previously opened with timerfd_create(2).
|
|
|
|
* @param scale The multiplicative factor for the timer.
|
|
|
|
* @param log_seconds The exponential factor for the timer.
|
|
|
|
* @return Zero on success, non-zero otherwise.
|
|
|
|
*/
|
2013-03-19 00:08:20 +08:00
|
|
|
int set_tmo_log(int fd, unsigned int scale, int log_seconds);
|
|
|
|
|
2013-10-25 20:45:33 +08:00
|
|
|
/**
|
|
|
|
* Utility function for setting a file descriptor timer.
|
|
|
|
*
|
|
|
|
* This function sets the timer 'fd' to a random value between M * 2^N and
|
|
|
|
* (M + S) * 2^N, where M is the value of the 'min' parameter, S is the value
|
|
|
|
* of the 'span' parameter, and N in the value of the 'log_seconds' parameter.
|
|
|
|
*
|
|
|
|
* @param fd A file descriptor previously opened with timerfd_create(2).
|
|
|
|
* @param min The minimum value for the timer.
|
|
|
|
* @param span The span value for the timer. Must be a positive value.
|
|
|
|
* @param log_seconds The exponential factor for the timer.
|
|
|
|
* @return Zero on success, non-zero otherwise.
|
|
|
|
*/
|
|
|
|
int set_tmo_random(int fd, int min, int span, int log_seconds);
|
|
|
|
|
2013-03-19 00:08:20 +08:00
|
|
|
/**
|
|
|
|
* Utility function for setting or resetting a file descriptor timer.
|
|
|
|
*
|
|
|
|
* This function sets the timer 'fd' to the value of the 'seconds' parameter.
|
|
|
|
*
|
|
|
|
* Passing 'seconds' as zero disables the timer.
|
|
|
|
*
|
|
|
|
* @param fd A file descriptor previously opened with timerfd_create(2).
|
|
|
|
* @param seconds The timeout value for the timer.
|
|
|
|
* @return Zero on success, non-zero otherwise.
|
|
|
|
*/
|
|
|
|
int set_tmo_lin(int fd, int seconds);
|
2013-01-30 23:28:54 +08:00
|
|
|
|
2014-08-14 21:56:01 +08:00
|
|
|
/**
|
|
|
|
* Sets port's fault file descriptor timer.
|
|
|
|
* Passing both 'scale' and 'log_seconds' as zero disables the timer.
|
|
|
|
*
|
|
|
|
* @param fd A port instance.
|
|
|
|
* @param scale The multiplicative factor for the timer.
|
|
|
|
* @param log_seconds The exponential factor for the timer.
|
|
|
|
* @return Zero on success, non-zero otherwise.
|
|
|
|
*/
|
|
|
|
int port_set_fault_timer_log(struct port *port,
|
|
|
|
unsigned int scale, int log_seconds);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets port's fault file descriptor timer.
|
|
|
|
* Passing 'seconds' as zero disables the timer.
|
|
|
|
*
|
|
|
|
* @param fd A port instance.
|
|
|
|
* @param seconds The timeout value for the timer.
|
|
|
|
* @return Zero on success, non-zero otherwise.
|
|
|
|
*/
|
|
|
|
int port_set_fault_timer_lin(struct port *port, int seconds);
|
|
|
|
|
2013-03-19 00:08:21 +08:00
|
|
|
/**
|
|
|
|
* Returns a port's last fault type.
|
|
|
|
*
|
|
|
|
* @param port A port instance.
|
|
|
|
* @return One of the @ref fault_type values.
|
|
|
|
*/
|
|
|
|
enum fault_type last_fault_type(struct port *port);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fills passed in struct fault_interval with the value associated to a
|
|
|
|
* port and fault type.
|
|
|
|
*
|
|
|
|
* @param port A port instance.
|
|
|
|
* @param ft Fault type.
|
|
|
|
* @param i Pointer to the struct which will be filled in.
|
|
|
|
*/
|
2017-01-04 03:55:33 +08:00
|
|
|
void fault_interval(struct port *port, enum fault_type ft,
|
|
|
|
struct fault_interval *i);
|
2013-03-19 00:08:21 +08:00
|
|
|
|
2018-10-04 00:41:50 +08:00
|
|
|
/**
|
|
|
|
* Obtain the BMCA type of the port.
|
|
|
|
*
|
|
|
|
* @param port A port instance.
|
|
|
|
* @return bmca type.
|
|
|
|
*/
|
|
|
|
enum bmca_select port_bmca(struct port *p);
|
|
|
|
|
2015-11-02 12:34:16 +08:00
|
|
|
/**
|
|
|
|
* Release all of the memory in the TC transmit descriptor cache.
|
|
|
|
*/
|
|
|
|
void tc_cleanup(void);
|
|
|
|
|
2011-11-05 02:20:23 +08:00
|
|
|
#endif
|