Add a functional framework to manage the clock and its ports.

This commit only adds support for forwarding the management messages.
The actual local effects of the management commands still need to be
implemented.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
master
Richard Cochran 2012-07-29 14:31:30 +02:00
parent d308df8e27
commit 4f04c4139d
4 changed files with 138 additions and 0 deletions

96
clock.c
View File

@ -32,6 +32,7 @@
#include "port.h" #include "port.h"
#include "servo.h" #include "servo.h"
#include "print.h" #include "print.h"
#include "tlv.h"
#include "util.h" #include "util.h"
#define FAULT_RESET_SECONDS 15 #define FAULT_RESET_SECONDS 15
@ -67,6 +68,11 @@ struct clock the_clock;
static void handle_state_decision_event(struct clock *c); static void handle_state_decision_event(struct clock *c);
static int cid_eq(struct ClockIdentity *a, struct ClockIdentity *b)
{
return 0 == memcmp(a, b, sizeof(*a));
}
static void clock_destroy(struct clock *c) static void clock_destroy(struct clock *c)
{ {
int i; int i;
@ -177,6 +183,22 @@ static void clock_update_slave(struct clock *c)
c->tds.timeSource = msg->announce.timeSource; c->tds.timeSource = msg->announce.timeSource;
} }
static int forwarding(struct port *p)
{
enum port_state ps = port_state(p);
switch (ps) {
case PS_MASTER:
case PS_GRAND_MASTER:
case PS_SLAVE:
case PS_UNCALIBRATED:
case PS_PRE_MASTER:
return 1;
default:
break;
}
return 0;
}
/* public methods */ /* public methods */
UInteger8 clock_class(struct clock *c) UInteger8 clock_class(struct clock *c)
@ -322,6 +344,80 @@ void clock_install_fda(struct clock *c, struct port *p, struct fdarray fda)
} }
} }
void clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
{
int i, pdulen;
struct port *fwd;
struct management_tlv *mgt;
struct ClockIdentity *tcid, wildcard = {
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
};
/* Forward this message out all eligible ports. */
if (forwarding(p) && msg->management.boundaryHops) {
pdulen = msg->header.messageLength;
msg->management.boundaryHops--;
msg_pre_send(msg);
for (i = 0; i < c->nports; i++) {
fwd = c->port[i];
if (fwd != p && forwarding(fwd) &&
port_forward(fwd, msg, pdulen))
pr_err("port %d: management forward failed", i);
}
msg_post_recv(msg, pdulen);
msg->management.boundaryHops++;
}
/* Apply this message to the local clock and ports. */
tcid = &msg->management.targetPortIdentity.clockIdentity;
if (!cid_eq(tcid, &wildcard) && !cid_eq(tcid, &c->dds.clockIdentity)) {
return;
}
if (msg->tlv_count != 1) {
return;
}
mgt = (struct management_tlv *) msg->management.suffix;
switch (mgt->id) {
case USER_DESCRIPTION:
case SAVE_IN_NON_VOLATILE_STORAGE:
case RESET_NON_VOLATILE_STORAGE:
case INITIALIZE:
case FAULT_LOG:
case FAULT_LOG_RESET:
case DEFAULT_DATA_SET:
case CURRENT_DATA_SET:
case PARENT_DATA_SET:
case TIME_PROPERTIES_DATA_SET:
case PRIORITY1:
case PRIORITY2:
case DOMAIN:
case SLAVE_ONLY:
case TIME:
case CLOCK_ACCURACY:
case UTC_PROPERTIES:
case TRACEABILITY_PROPERTIES:
case TIMESCALE_PROPERTIES:
case PATH_TRACE_LIST:
case PATH_TRACE_ENABLE:
case GRANDMASTER_CLUSTER_TABLE:
case ACCEPTABLE_MASTER_TABLE:
case ACCEPTABLE_MASTER_MAX_TABLE_SIZE:
case ALTERNATE_TIME_OFFSET_ENABLE:
case ALTERNATE_TIME_OFFSET_NAME:
case ALTERNATE_TIME_OFFSET_MAX_KEY:
case ALTERNATE_TIME_OFFSET_PROPERTIES:
case TRANSPARENT_CLOCK_DEFAULT_DATA_SET:
case PRIMARY_DOMAIN:
break;
default:
for (i = 0; i < c->nports; i++) {
if (port_manage(c->port[i], p, msg))
break;
}
break;
}
}
struct parentDS *clock_parent_ds(struct clock *c) struct parentDS *clock_parent_ds(struct clock *c)
{ {
return &c->dad; return &c->dad;

10
clock.h
View File

@ -26,6 +26,8 @@
#include "tmv.h" #include "tmv.h"
#include "transport.h" #include "transport.h"
struct ptp_message; /*forward declaration*/
#define MAX_PORTS 8 #define MAX_PORTS 8
/** Defines a network interface, with PTP options. */ /** Defines a network interface, with PTP options. */
@ -106,6 +108,14 @@ struct ClockIdentity clock_identity(struct clock *c);
*/ */
void clock_install_fda(struct clock *c, struct port *p, struct fdarray fda); void clock_install_fda(struct clock *c, struct port *p, struct fdarray fda);
/**
* Manage the clock according to a given message.
* @param c The clock instance.
* @param p The port on which the message arrived.
* @param msg A management message.
*/
void clock_manage(struct clock *c, struct port *p, struct ptp_message *msg);
/** /**
* Obtain a clock's parent data set. * Obtain a clock's parent data set.
* @param c The clock instance. * @param c The clock instance.

14
port.c
View File

@ -1338,7 +1338,9 @@ enum fsm_event port_event(struct port *p, int fd_index)
event = EV_STATE_DECISION_EVENT; event = EV_STATE_DECISION_EVENT;
break; break;
case SIGNALING: case SIGNALING:
break;
case MANAGEMENT: case MANAGEMENT:
clock_manage(p->clock, p, msg);
break; break;
} }
@ -1346,6 +1348,18 @@ enum fsm_event port_event(struct port *p, int fd_index)
return event; return event;
} }
int port_forward(struct port *p, struct ptp_message *msg, int msglen)
{
int cnt;
cnt = transport_send(p->trp, &p->fda, 0, msg, msglen, &msg->hwts);
return cnt <= 0 ? -1 : 0;
}
int port_manage(struct port *p, struct port *ingress, struct ptp_message *msg)
{
return 0;
}
struct port *port_open(struct port_defaults *pod, struct port *port_open(struct port_defaults *pod,
int phc_index, int phc_index,
char *name, char *name,

18
port.h
View File

@ -77,6 +77,24 @@ void port_dispatch(struct port *p, enum fsm_event event, int mdiff);
*/ */
enum fsm_event port_event(struct port *port, int fd_index); 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.
* @param msglen The length of the message in bytes.
* @return Zero on success, non-zero otherwise.
*/
int port_forward(struct port *p, struct ptp_message *msg, int msglen);
/**
* 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 Zero if the message is valid, non-zero otherwise.
*/
int port_manage(struct port *p, struct port *ingress, struct ptp_message *msg);
/** /**
* Open a network port. * Open a network port.
* @param pod A pointer to a default port data set for this port. * @param pod A pointer to a default port data set for this port.