1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
|
/**
* @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
#include "dm.h"
#include "fd.h"
#include "foreign.h"
#include "fsm.h"
#include "notification.h"
#include "transport.h"
#define POW2_41 ((double)(1ULL << 41))
/* forward declarations */
struct interface;
struct clock;
/** Opaque type. */
struct port;
/** The port identity that matches any port. */
extern const struct PortIdentity wildcard_pid;
/**
* Returns the dataset from a port's best foreign clock record, if any
* has yet been discovered. This function does not bring the returned
* dataset up to date, so the caller should invoke port_compute_best()
* beforehand.
*
* @param port A pointer previously obtained via port_open().
* @return A pointer to a dataset, or NULL.
*/
struct dataset *port_best_foreign(struct port *port);
/**
* 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.
* @param mdiff Whether a new master has been selected.
*/
void port_dispatch(struct port *p, enum fsm_event event, int mdiff);
/**
* 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);
/**
* 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.
*/
int port_forward(struct port *p, struct ptp_message *msg);
/**
* 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, negative errno value otherwise.
*/
int port_forward_to(struct port *p, struct ptp_message *msg);
/**
* 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.
* @param event One of the @ref transport_event enumeration values.
*/
int port_prepare_and_send(struct port *p, struct ptp_message *msg,
enum transport_event event);
/**
* 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);
/**
* Obtain a port number.
* @param p A port instance.
* @return The port number of 'p'.
*/
int port_number(struct port *p);
/**
* Obtain a port's name for logging purposes.
* @param p A port instance.
* @return Loggable name of 'p'.
*/
const char *port_log_name(struct port *p);
/**
* 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);
/**
* 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.
* @return 1 if the message was responded to, 0 if it did not apply
* to the port, -1 if it was invalid.
*/
int port_manage(struct port *p, struct port *ingress, struct ptp_message *msg);
/**
* 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.
*/
int port_management_error(struct PortIdentity pid, struct port *ingress,
struct ptp_message *req, Enumeration16 error_id);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* Open a network port.
* @param phc_device The name of PHC device as found on the command line.
* @param phc_index The PHC device index for the network device.
* @param timestamping The timestamping mode for this port.
* @param number An arbitrary number assigned to this port.
* @param interface The interface data
* @param clock A pointer to the system PTP clock.
* @return A pointer to an open port on success, or NULL otherwise.
*/
struct port *port_open(const char *phc_device,
int phc_index,
enum timestamp_type timestamping,
int number,
struct interface *interface,
struct clock *clock);
struct ptp_message *port_signaling_construct(struct port *p,
const struct PortIdentity *tpid);
/**
* 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);
/**
* Return port's delay mechanism method.
* @param port A port instance.
* @return one of the @ref delay_mechanism values.
*/
enum delay_mechanism port_delay_mechanism(struct port *port);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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.
*/
int set_tmo_log(int fd, unsigned int scale, int log_seconds);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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.
*/
void fault_interval(struct port *port, enum fault_type ft,
struct fault_interval *i);
/**
* Obtain the BMCA type of the port.
*
* @param port A port instance.
* @return bmca type.
*/
enum bmca_select port_bmca(struct port *p);
/**
* Release all of the memory in the TC transmit descriptor cache.
*/
void tc_cleanup(void);
/**
* Update port's unicast state if port's unicast_state_dirty is true.
*
* @param port A port instance.
*/
void port_update_unicast_state(struct port *p);
#endif
|