bmc: Allow alternative data set comparison algorithms.

Instead of using a hard coded algorithm, let the caller provide the
function that performs the comparison.  This will allow implementing
alternative algorithms from PTP profiles.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
master
Richard Cochran 2017-02-14 16:56:04 +01:00
parent b05991dbb8
commit 1b3ef0d195
3 changed files with 10 additions and 7 deletions

9
bmc.c
View File

@ -120,7 +120,8 @@ int dscmp(struct dataset *a, struct dataset *b)
return diff < 0 ? A_BETTER : B_BETTER; return diff < 0 ? A_BETTER : B_BETTER;
} }
enum port_state bmc_state_decision(struct clock *c, struct port *r) enum port_state bmc_state_decision(struct clock *c, struct port *r,
int (*compare)(struct dataset *a, struct dataset *b))
{ {
struct dataset *clock_ds, *clock_best, *port_best; struct dataset *clock_ds, *clock_best, *port_best;
enum port_state ps; enum port_state ps;
@ -134,14 +135,14 @@ enum port_state bmc_state_decision(struct clock *c, struct port *r)
return ps; return ps;
if (clock_class(c) <= 127) { if (clock_class(c) <= 127) {
if (dscmp(clock_ds, port_best) > 0) { if (compare(clock_ds, port_best) > 0) {
return PS_GRAND_MASTER; /*M1*/ return PS_GRAND_MASTER; /*M1*/
} else { } else {
return PS_PASSIVE; /*P1*/ return PS_PASSIVE; /*P1*/
} }
} }
if (dscmp(clock_ds, clock_best) > 0) { if (compare(clock_ds, clock_best) > 0) {
return PS_GRAND_MASTER; /*M2*/ return PS_GRAND_MASTER; /*M2*/
} }
@ -149,7 +150,7 @@ enum port_state bmc_state_decision(struct clock *c, struct port *r)
return PS_SLAVE; /*S1*/ return PS_SLAVE; /*S1*/
} }
if (dscmp(clock_best, port_best) == A_BETTER_TOPO) { if (compare(clock_best, port_best) == A_BETTER_TOPO) {
return PS_PASSIVE; /*P2*/ return PS_PASSIVE; /*P2*/
} else { } else {
return PS_MASTER; /*M3*/ return PS_MASTER; /*M3*/

6
bmc.h
View File

@ -28,12 +28,14 @@
* BMC state decision algorithm. * BMC state decision algorithm.
* @param c The local clock. * @param c The local clock.
* @param r The port in question. * @param r The port in question.
* @param compare The data set comparison algorithm.
* @return A @ref port_state value as the recommended state. * @return A @ref port_state value as the recommended state.
*/ */
enum port_state bmc_state_decision(struct clock *c, struct port *r); enum port_state bmc_state_decision(struct clock *c, struct port *r,
int (*comapre)(struct dataset *a, struct dataset *b));
/** /**
* Compare two data sets. * Compare two data sets using the algorithm defined in IEEE 1588.
* @param a A dataset to compare. * @param a A dataset to compare.
* @param b A dataset to compare. * @param b A dataset to compare.
* @return An integer less than, equal to, or greater than zero * @return An integer less than, equal to, or greater than zero

View File

@ -1723,7 +1723,7 @@ static void handle_state_decision_event(struct clock *c)
LIST_FOREACH(piter, &c->ports, list) { LIST_FOREACH(piter, &c->ports, list) {
enum port_state ps; enum port_state ps;
enum fsm_event event; enum fsm_event event;
ps = bmc_state_decision(c, piter); ps = bmc_state_decision(c, piter, c->dscmp);
switch (ps) { switch (ps) {
case PS_LISTENING: case PS_LISTENING:
event = EV_NONE; event = EV_NONE;