Skip to content

Commit 7dd53e3

Browse files
committed
Use NTP for Samsung AU9000 running AirPlay 377.25.06
1 parent ae06722 commit 7dd53e3

2 files changed

Lines changed: 33 additions & 0 deletions

File tree

internal/airplay/compatibility.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ func compatibilityForReceiver(info *ReceiverInfo, encrypted, audioEnabled bool)
8585
// mirroring session.
8686
if encrypted && info.HasFeature(featurePTP) && supportsPTPSourceVersion(info.SourceVersion) {
8787
policy.timing = timingProtocolPTP
88+
// Samsung AU9000 with this AirPlay version advertises PTP but omits
89+
// timingPeerInfo.ClockID in SETUP. NTP works on the same receiver.
90+
// Keep the exception limited to the observed model/version pair.
91+
if info.Model == "UAU9000" && info.SourceVersion == "377.25.06" {
92+
policy.timing = timingProtocolNTP
93+
}
8894
}
8995

9096
return policy, nil

internal/airplay/compatibility_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,30 @@ func TestHybridAudioDescriptorLayouts(t *testing.T) {
259259
t.Fatalf("plaintext streamConnections encryption flag = %#v, want false", rtp["streamConnectionKeyUseStreamEncryptionKey"])
260260
}
261261
}
262+
263+
func TestSamsungAU9000TimingException(t *testing.T) {
264+
for _, test := range []struct {
265+
name, model, version, want string
266+
}{
267+
{"observed receiver", "UAU9000", "377.25.06", timingProtocolNTP},
268+
{"different model", "another model", "377.25.06", timingProtocolPTP},
269+
{"missing model", "", "377.25.06", timingProtocolPTP},
270+
{"different version", "UAU9000", "377.25.07", timingProtocolPTP},
271+
} {
272+
t.Run(test.name, func(t *testing.T) {
273+
info := receiverWithFeatures(featurePTP, featureAudioStreamConnectionSetup)
274+
info.SourceVersion = test.version
275+
baseline := mustCompatibility(t, &info, true)
276+
info.Model = test.model
277+
got := mustCompatibility(t, &info, true)
278+
if got.timing != test.want {
279+
t.Fatalf("timing = %q, want %q", got.timing, test.want)
280+
}
281+
// The quirk must not change audio negotiation or key placement.
282+
got.timing = baseline.timing
283+
if !reflect.DeepEqual(got, baseline) {
284+
t.Fatalf("timing exception changed another policy field: got %+v, want %+v", got, baseline)
285+
}
286+
})
287+
}
288+
}

0 commit comments

Comments
 (0)