diff --git a/ptp/sptp/client/bmca.go b/ptp/sptp/client/bmca.go index 1c6c9cd..4a0731e 100644 --- a/ptp/sptp/client/bmca.go +++ b/ptp/sptp/client/bmca.go @@ -36,7 +36,8 @@ func bmca(msgs []*ptp.Announce, prios map[ptp.ClockIdentity]int) *ptp.Announce { best = b } } - if best.AnnounceBody.GrandmasterClockQuality.ClockClass >= ptp.ClockClass13 { + // Never select GM in worse than holdover status or with clock quality worse than 10 microseconds + if best.AnnounceBody.GrandmasterClockQuality.ClockClass > ptp.ClockClass7 || best.AnnounceBody.GrandmasterClockQuality.ClockAccuracy > ptp.ClockAccuracyMicrosecond10 { return nil } return best diff --git a/ptp/sptp/client/bmca_test.go b/ptp/sptp/client/bmca_test.go index d396f3c..e106d4c 100644 --- a/ptp/sptp/client/bmca_test.go +++ b/ptp/sptp/client/bmca_test.go @@ -37,8 +37,15 @@ func TestBmcaProperlyUsesLocalPriority(t *testing.T) { } func TestBmcaNoMasterForCalibrating(t *testing.T) { - best := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 1, GrandmasterClockQuality: ptp.ClockQuality{ClockClass: ptp.ClockClass52}}} - worse := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 2, GrandmasterClockQuality: ptp.ClockQuality{ClockClass: ptp.ClockClass13}}} + best := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 1, GrandmasterClockQuality: ptp.ClockQuality{ClockClass: ptp.ClockClass13}}} + worse := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 2, GrandmasterClockQuality: ptp.ClockQuality{ClockClass: ptp.ClockClass52}}} + selected := bmca([]*ptp.Announce{&best, &worse}, map[ptp.ClockIdentity]int{1: 2, 2: 1}) + require.Empty(t, selected) +} + +func TestBmcaNoMasterForLowAccuracy(t *testing.T) { + best := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 1, GrandmasterClockQuality: ptp.ClockQuality{ClockAccuracy: ptp.ClockAccuracyMicrosecond100}}} + worse := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 2, GrandmasterClockQuality: ptp.ClockQuality{ClockAccuracy: ptp.ClockAccuracySecond10}}} selected := bmca([]*ptp.Announce{&best, &worse}, map[ptp.ClockIdentity]int{1: 2, 2: 1}) require.Empty(t, selected) }