Signed-off-by: Richard Cochran <richardcoch...@gmail.com> --- clock.c | 2 +- makefile | 2 +- p2p_tc.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ port.c | 3 ++ port_private.h | 3 ++ 5 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 p2p_tc.c
diff --git a/clock.c b/clock.c index 26e69a6..e5554bc 100644 --- a/clock.c +++ b/clock.c @@ -872,9 +872,9 @@ struct clock *clock_create(enum clock_type type, struct config *config, switch (type) { case CLOCK_TYPE_ORDINARY: case CLOCK_TYPE_BOUNDARY: + case CLOCK_TYPE_P2P: c->type = type; break; - case CLOCK_TYPE_P2P: case CLOCK_TYPE_E2E: case CLOCK_TYPE_MANAGEMENT: return NULL; diff --git a/makefile b/makefile index 8488679..ac9de87 100644 --- a/makefile +++ b/makefile @@ -25,7 +25,7 @@ LDLIBS = -lm -lrt $(EXTRA_LDFLAGS) PRG = ptp4l pmc phc2sys hwstamp_ctl phc_ctl timemaster OBJ = bmc.o clock.o clockadj.o clockcheck.o config.o fault.o \ filter.o fsm.o hash.o linreg.o mave.o mmedian.o msg.o ntpshm.o nullf.o phc.o \ - pi.o port.o print.o ptp4l.o raw.o rtnl.o servo.o sk.o stats.o tc.o tlv.o \ + pi.o port.o print.o ptp4l.o p2p_tc.o raw.o rtnl.o servo.o sk.o stats.o tc.o tlv.o \ transport.o tsproc.o udp.o udp6.o uds.o util.o version.o OBJECTS = $(OBJ) hwstamp_ctl.o phc2sys.o phc_ctl.o pmc.o pmc_common.o \ diff --git a/p2p_tc.c b/p2p_tc.c new file mode 100644 index 0000000..eea09e2 --- /dev/null +++ b/p2p_tc.c @@ -0,0 +1,155 @@ +/** + * @file p2p_tc.c + * @note Copyright (C) 2015 Richard Cochran <richardcoch...@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. + */ +#include <errno.h> + +#include "port.h" +#include "port_private.h" +#include "print.h" +#include "tc.h" + +int p2p_dispatch(struct port *p, enum fsm_event event, int mdiff) +{ + enum port_state next; + struct fault_interval fti; + int clear_asap = 0; + + next = ptp_fsm(p->state, event, mdiff); + + if (!fault_interval(p, last_fault_type(p), &fti)) { + if (fti.val == FRI_ASAP && fti.type == FTMO_LOG2_SECONDS) { + clear_asap = 1; + } + if (fti.val == 0 && fti.type == FTMO_LINEAR_SECONDS) { + clear_asap = 1; + } + } + if (PS_INITIALIZING == next || (PS_FAULTY == next && clear_asap)) { + /* Special case, skip to listening. */ + if (port_is_enabled(p)) { + port_disable(p); + } + next = port_initialize(p) ? PS_FAULTY : PS_LISTENING; + port_show_transition(p, next, event); + p->state = next; + if (next == PS_LISTENING && portnum(p)) { + port_set_delay_tmo(p); + } + port_clr_tmo(p->fda.fd[FD_ANNOUNCE_TIMER]); + port_notify_event(p, NOTIFY_PORT_STATE); + return 1; + } + + return 0; +} + +enum fsm_event p2p_event(struct port *p, int fd_index) +{ + enum fsm_event event = EV_NONE; + struct ptp_message *msg; + int cnt, fd = p->fda.fd[fd_index], err; + + switch (fd_index) { + case FD_ANNOUNCE_TIMER: + case FD_SYNC_RX_TIMER: + pr_err("unexpected timer expiration"); + return EV_NONE; + case FD_DELAY_TIMER: + pr_debug("port %hu: delay timeout", portnum(p)); + port_set_delay_tmo(p); + tc_prune(p); + return port_delay_request(p) ? EV_FAULT_DETECTED : EV_NONE; + case FD_QUALIFICATION_TIMER: + case FD_MANNO_TIMER: + case FD_SYNC_TX_TIMER: + pr_err("unexpected timer expiration"); + return EV_NONE; + } + + msg = msg_allocate(); + if (!msg) + return EV_FAULT_DETECTED; + + msg->hwts.type = p->timestamping; + + cnt = transport_recv(p->trp, fd, msg); + if (cnt <= 0) { + pr_err("port %hu: recv message failed", portnum(p)); + msg_put(msg); + return EV_FAULT_DETECTED; + } + err = msg_post_recv(msg, cnt); + if (err) { + switch (err) { + case -EBADMSG: + pr_err("port %hu: bad message", portnum(p)); + break; + case -ETIME: + pr_err("port %hu: received %s without timestamp", + portnum(p), msg_type_string(msg_type(msg))); + break; + case -EPROTO: + pr_debug("port %hu: ignoring message", portnum(p)); + break; + } + msg_put(msg); + return EV_NONE; + } + if (msg_sots_valid(msg)) { + ts_add(&msg->hwts.ts, -p->rx_timestamp_offset); + } + if (msg->header.flagField[0] & UNICAST) { + pl_warning(600, "cannot handle unicast messages!"); + goto out; + } + + switch (msg_type(msg)) { + case SYNC: + if (tc_fwd_event(p, msg)) + event = EV_FAULT_DETECTED; + break; + case DELAY_REQ: + break; + case PDELAY_REQ: + if (process_pdelay_req(p, msg)) + event = EV_FAULT_DETECTED; + break; + case PDELAY_RESP: + if (process_pdelay_resp(p, msg)) + event = EV_FAULT_DETECTED; + break; + case FOLLOW_UP: + if (tc_fwd_folup(p, msg)) + event = EV_FAULT_DETECTED; + break; + case DELAY_RESP: + break; + case PDELAY_RESP_FOLLOW_UP: + process_pdelay_resp_fup(p, msg); + break; + case ANNOUNCE: + case SIGNALING: + case MANAGEMENT: + if (tc_forward(p, msg)) + event = EV_FAULT_DETECTED; + break; + } +out: + msg_put(msg); + return event; +} diff --git a/port.c b/port.c index 1b2f4e5..8d99675 100644 --- a/port.c +++ b/port.c @@ -2496,6 +2496,9 @@ struct port *port_open(int phc_index, p->event = bc_event; break; case CLOCK_TYPE_P2P: + p->dispatch = p2p_dispatch; + p->event = p2p_event; + break; case CLOCK_TYPE_E2E: case CLOCK_TYPE_MANAGEMENT: return NULL; diff --git a/port_private.h b/port_private.h index 2fc927a..083cf7b 100644 --- a/port_private.h +++ b/port_private.h @@ -120,6 +120,9 @@ struct port { #define portnum(p) (p->portIdentity.portNumber) +int p2p_dispatch(struct port *p, enum fsm_event event, int mdiff); +enum fsm_event p2p_event(struct port *p, int fd_index); + int port_clr_tmo(int fd); int port_delay_request(struct port *p); void port_disable(struct port *p); -- 2.1.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel