Skip to content

Commit 30e8c26

Browse files
committed
Use stable hash to determine if configuration number needs bumping
The old implementation would increase the configuration number on each server restart. This caused issues with e.g. Homepod that would reset room configurations. We need a stable hash that is the same accross reboots and maybe even hardware. We don't need a good distribution of this hash, but importantly a hash that is unique for changes to device configuration.
1 parent 60d7875 commit 30e8c26

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

Sources/HAP/Server/Configuration.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ extension Device {
5353
// must be unique for the lifetime of the server/ client pairing.
5454
internal var aidForAccessorySerialNumber = [String: InstanceID]()
5555

56+
// Hash of the attached accessories, services and characteristics. Used
57+
// to assert if the current configuration number should be updated after
58+
// initializing / modifying list of accessories.
59+
internal var stableHash: Int = 0
60+
5661
private var aidGenerator = AIDGenerator()
5762

5863
// The next aid - should be checked against existing devices to ensure it is unique

Sources/HAP/Server/Device.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,11 @@ public class Device {
238238
/// - write the configuration to storage
239239
/// - notify interested parties of the change
240240
func updatedConfiguration() {
241-
configuration.number = configuration.number &+ 1
241+
var newStableHash = generateStableHash()
242+
if newStableHash != configuration.stableHash {
243+
configuration.number = configuration.number &+ 1
244+
configuration.stableHash = newStableHash
245+
}
242246
if configuration.number < 1 {
243247
configuration.number = 1
244248
}
@@ -247,6 +251,22 @@ public class Device {
247251
notifyConfigurationChange()
248252
}
249253

254+
/// Generate uniqueness hash for device configuration, used to determine
255+
/// if the configuration number should be updated.
256+
func generateStableHash() -> Int {
257+
var hash = 0
258+
for accessory in accessories {
259+
hash ^= 17 &* accessory.aid
260+
for service in accessory.services {
261+
hash ^= 19 &* service.iid
262+
for characteristic in service.characteristics {
263+
hash ^= 23 &* characteristic.iid
264+
}
265+
}
266+
}
267+
return hash
268+
}
269+
250270
/// Notify the server that the config record has changed
251271
func notifyConfigurationChange() {
252272
server?.updateDiscoveryRecord()

0 commit comments

Comments
 (0)