Commit 9d666fc5 authored by Davide Ciminaghi's avatar Davide Ciminaghi

compliance, 9.3.2.5 c/d: qualify masters for bmc on announce reception

parent 68600044
......@@ -31,6 +31,7 @@
#define PP_DEFAULT_SYNC_INTERVAL 0 /* -7 in 802.1AS */
#define PP_DEFAULT_SYNC_RECEIPT_TIMEOUT 3
#define PP_DEFAULT_ANNOUNCE_RECEIPT_TIMEOUT 20 /* 3 by default */
#define PP_FOREIGN_MASTER_TIME_WINDOW 4
/* Clock classes (pag 55, PTP-2008). See ppsi-manual for an explanation */
#define PP_CLASS_SLAVE_ONLY 255
......
......@@ -300,11 +300,24 @@ int bmc(struct pp_instance *ppi)
return ppi->state;
}
/* Get first qualified master as best */
for (i = 0, best = -1; i < ppi->frgn_rec_num && best == -1; i++)
if (frgn_master[i].qualified_for_bmc)
best = i;
if (best == -1) {
pp_diag(ppi, bmc, 1, "No qualified masters, skipping BMC\n");
return ppi->state;
}
/* Find Erbest, 9.3.2.3 */
for (i = 1, best = 0; i < ppi->frgn_rec_num; i++)
for (i = 0; i < ppi->frgn_rec_num; i++) {
if (!frgn_master[i].qualified_for_bmc)
continue;
if (bmc_dataset_cmp(ppi, &frgn_master[i], &frgn_master[best])
< 0)
best = i;
}
pp_diag(ppi, bmc, 1,"Best foreign master is %i/%i\n", best,
ppi->frgn_rec_num);
......
......@@ -113,6 +113,44 @@ static void process_ann_ts(struct pp_instance *ppi,
m->saved_timestamps = min(m->saved_timestamps + 1, 2);
}
/*
* Returns ts_window in milliseconds
*/
static unsigned long ts_window(struct pp_instance *ppi)
{
struct DSPort *port = DSPOR(ppi);
unsigned long ann_timeout = 1000 * (port->announceReceiptTimeout <<
port->logAnnounceInterval);
return ann_timeout * PP_FOREIGN_MASTER_TIME_WINDOW;
}
/*
* Qualify a master: we need at least 2 announce messages in 4 announce
* intervals
*/
static void qualify_master(struct pp_instance *ppi,
struct pp_frgn_master *m,
unsigned long now)
{
/* 9.3.2.5 c and d */
m->qualified_for_bmc = m->ann.stepsRemoved < 255 &&
m->saved_timestamps > 1 &&
!time_after(now, m->last_ann_ts[1] + ts_window(ppi));
}
/*
* Walk through all masters and qualify them for bmc
*/
static void qualify_masters(struct pp_instance *ppi, unsigned long now)
{
int i;
struct pp_frgn_master *m;
for (i = 0, m = ppi->frgn_master; i < PP_NR_FOREIGN_RECORDS; m++, i++)
qualify_master(ppi, m, now);
}
/* Called by this file, basically when an announce is got, all states */
static void st_com_add_foreign(struct pp_instance *ppi, unsigned char *buf,
unsigned long now)
......@@ -172,6 +210,7 @@ int st_com_slave_handle_announce(struct pp_instance *ppi, unsigned char *buf,
/*Reset Timer handling Announce receipt timeout*/
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
qualify_masters(ppi, now);
ppi->next_state = bmc(ppi); /* got a new announce: run bmc */
if (pp_hooks.handle_announce)
......@@ -396,6 +435,7 @@ int st_com_master_handle_announce(struct pp_instance *ppi, unsigned char *buf,
pp_diag(ppi, bmc, 2, "Announce message from another foreign master\n");
st_com_add_foreign(ppi, buf, now);
qualify_masters(ppi, now);
ppi->next_state = bmc(ppi); /* got a new announce: run bmc */
if (pp_hooks.handle_announce)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment