Skip to content

Commit f466f36

Browse files
committed
OcaConnectionBroker: fix broken emission of device removal events
1 parent fe9ca24 commit f466f36

File tree

1 file changed

+49
-37
lines changed

1 file changed

+49
-37
lines changed

Sources/SwiftOCA/OCA/Browsing/ConnectionBroker.swift

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -318,33 +318,59 @@ public actor OcaConnectionBroker {
318318
}
319319
}
320320

321-
private func _onBrowseResult(_ result: OcaNetworkAdvertisingServiceBrowserResult) async throws {
322-
var expiringConnection: DeviceConnection?
323-
324-
let event = try await Event(browserResult: result) // will resolve
325-
let device = DeviceInfo(deviceIdentifier: event.deviceIdentifier, serviceInfo: result.info)
326-
327-
switch event.eventType {
328-
case .deviceRemoved:
329-
expiringConnection = _removeConnection(for: event.deviceIdentifier)
330-
case .deviceAdded:
331-
if let existingDevice = _devices[event.deviceIdentifier],
332-
(try? existingDevice.addresses) != (try? device.addresses),
333-
let existingConnection = _removeConnection(for: event.deviceIdentifier)
334-
{
335-
// notify connection layer of new address
336-
if let mutableConnection = existingConnection.connection as? Ocp1MutableConnection {
337-
mutableConnection.deviceAddress = try device.firstAddress
338-
}
321+
private func _onBrowserDeviceAdded(
322+
_ serviceInfo: any OcaNetworkAdvertisingServiceInfo
323+
) async throws
324+
-> Event
325+
{
326+
let deviceIdentifier = try await DeviceIdentifier(serviceInfo: serviceInfo)
327+
let event = Event(eventType: .deviceAdded, deviceIdentifier: deviceIdentifier)
328+
let device = DeviceInfo(deviceIdentifier: event.deviceIdentifier, serviceInfo: serviceInfo)
329+
330+
if let existingDevice = _devices[event.deviceIdentifier],
331+
(try? existingDevice.addresses) != (try? device.addresses),
332+
let existingConnection = _removeConnection(for: event.deviceIdentifier)
333+
{
334+
// notify connection layer of new address
335+
if let mutableConnection = existingConnection.connection as? Ocp1MutableConnection {
336+
mutableConnection.deviceAddress = try device.firstAddress
339337
}
340-
// commit the new device
341-
_devices[event.deviceIdentifier] = device
342-
default:
343-
return
344338
}
345339

346-
_eventsContinuation.yield(event)
340+
_devices[event.deviceIdentifier] = device
341+
return event
342+
}
343+
344+
private func _onBrowserDeviceRemoved(
345+
_ serviceInfo: any OcaNetworkAdvertisingServiceInfo
346+
) async throws
347+
-> Event
348+
{
349+
// note: we can't initialize a DeviceIdentifier() from the serviceInfo because a removed service
350+
// cannot be resolved
351+
guard let deviceIdentifier = _devices.values.first(where: {
352+
$0.serviceInfo == AnyOcaNetworkAdvertisingServiceInfo(serviceInfo)
353+
})?.deviceIdentifier else {
354+
throw Ocp1Error.serviceResolutionFailed
355+
}
356+
357+
let event = Event(eventType: .deviceRemoved, deviceIdentifier: deviceIdentifier)
358+
let expiringConnection = _removeConnection(for: deviceIdentifier)
359+
_devices[deviceIdentifier] = nil
347360
await expiringConnection?.expire()
361+
362+
return event
363+
}
364+
365+
private func _onBrowseResult(_ result: OcaNetworkAdvertisingServiceBrowserResult) async throws {
366+
let event = switch result {
367+
case let .added(serviceInfo):
368+
try await _onBrowserDeviceAdded(serviceInfo)
369+
case let .removed(serviceInfo):
370+
try await _onBrowserDeviceRemoved(serviceInfo)
371+
}
372+
373+
_eventsContinuation.yield(event)
348374
}
349375

350376
/// Initializes a new connection broker with the specified connection options.
@@ -510,18 +536,4 @@ extension OcaConnectionBroker.DeviceIdentifier {
510536
}
511537
}
512538

513-
extension OcaConnectionBroker.Event {
514-
init(browserResult: OcaNetworkAdvertisingServiceBrowserResult) async throws {
515-
let deviceIdentifier = try await OcaConnectionBroker
516-
.DeviceIdentifier(serviceInfo: browserResult.info)
517-
518-
switch browserResult {
519-
case .added:
520-
self = .init(eventType: .deviceAdded, deviceIdentifier: deviceIdentifier)
521-
case .removed:
522-
self = .init(eventType: .deviceRemoved, deviceIdentifier: deviceIdentifier)
523-
}
524-
}
525-
}
526-
527539
#endif

0 commit comments

Comments
 (0)