@mentra/glasses-media 3.4.0-dev.1209 → 3.4.0-dev.1211
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// When to ask iOS again to join the glasses hotspot.
|
|
4
|
+
///
|
|
5
|
+
/// iOS accepts a hotspot configuration and then makes one short directed scan for it. When that
|
|
6
|
+
/// scan misses the glasses' beacon, iOS shows "Unable to join the network", stays on the current
|
|
7
|
+
/// Wi-Fi and still reports the configuration as applied. Only the phone's current network shows
|
|
8
|
+
/// that the join failed, so a request that has not put the phone on the hotspot after a few
|
|
9
|
+
/// seconds is made again, a bounded number of times, within the join's overall deadline.
|
|
10
|
+
public struct HotspotReapplyPolicy {
|
|
11
|
+
/// Polls of the current network, half a second apart, before a request counts as missed.
|
|
12
|
+
public let pollsBeforeReapply: Int
|
|
13
|
+
/// Requests in one join, the first included.
|
|
14
|
+
public let maxApplies: Int
|
|
15
|
+
|
|
16
|
+
public init(pollsBeforeReapply: Int = 16, maxApplies: Int = 3) {
|
|
17
|
+
self.pollsBeforeReapply = pollsBeforeReapply
|
|
18
|
+
self.maxApplies = maxApplies
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// Whether to request the join again, with the phone not on the hotspot after `pollsSinceApply`
|
|
22
|
+
/// polls of the `applies`-th request.
|
|
23
|
+
public func shouldReapply(applies: Int, pollsSinceApply: Int) -> Bool {
|
|
24
|
+
applies < maxApplies && pollsSinceApply >= pollsBeforeReapply
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -17,6 +17,8 @@ public final class GlassesHotspotNetwork {
|
|
|
17
17
|
private var generation = 0
|
|
18
18
|
private var applying = false
|
|
19
19
|
private var ownsConfiguration = false
|
|
20
|
+
private var applies = 0
|
|
21
|
+
private let reapplyPolicy = HotspotReapplyPolicy()
|
|
20
22
|
private var cancelled = false
|
|
21
23
|
private var joinReply: ((Result<String, Error>) -> Void)?
|
|
22
24
|
private var leaveCompletion: HotspotLeaveCompletion?
|
|
@@ -63,6 +65,7 @@ public final class GlassesHotspotNetwork {
|
|
|
63
65
|
self.cancelled = false
|
|
64
66
|
self.applying = false
|
|
65
67
|
self.ownsConfiguration = false
|
|
68
|
+
self.applies = 0
|
|
66
69
|
self.joinReply = completion
|
|
67
70
|
self.startInterfaceMonitors(generation: gen)
|
|
68
71
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
|
@@ -324,12 +327,13 @@ public final class GlassesHotspotNetwork {
|
|
|
324
327
|
}
|
|
325
328
|
}
|
|
326
329
|
|
|
327
|
-
private func applyConfiguration(ssid: String, passphrase: String, generation gen: Int) {
|
|
330
|
+
private func applyConfiguration(ssid: String, passphrase: String, generation gen: Int, remaining: Int = 60) {
|
|
328
331
|
let config = NEHotspotConfiguration(ssid: ssid, passphrase: passphrase, isWEP: false)
|
|
329
332
|
config.joinOnce = false
|
|
330
333
|
applying = true
|
|
331
334
|
ownsConfiguration = true
|
|
332
|
-
|
|
335
|
+
applies += 1
|
|
336
|
+
logger.info("HOTSPOT_JOIN apply_start attempt=\(self.applies) ios_on_mac=\(ProcessInfo.processInfo.isiOSAppOnMac)")
|
|
333
337
|
NEHotspotConfigurationManager.shared.apply(config) { error in
|
|
334
338
|
self.queue.async {
|
|
335
339
|
guard gen == self.generation else { return }
|
|
@@ -347,12 +351,12 @@ public final class GlassesHotspotNetwork {
|
|
|
347
351
|
}
|
|
348
352
|
}
|
|
349
353
|
self.logger.info("HOTSPOT_JOIN apply_accepted")
|
|
350
|
-
self.waitForAddress(ssid: ssid, generation: gen, remaining:
|
|
354
|
+
self.waitForAddress(ssid: ssid, passphrase: passphrase, generation: gen, remaining: remaining, pollsSinceApply: 0)
|
|
351
355
|
}
|
|
352
356
|
}
|
|
353
357
|
}
|
|
354
358
|
|
|
355
|
-
private func waitForAddress(ssid: String, generation gen: Int, remaining: Int) {
|
|
359
|
+
private func waitForAddress(ssid: String, passphrase: String, generation gen: Int, remaining: Int, pollsSinceApply: Int) {
|
|
356
360
|
guard gen == generation, !cancelled else { return }
|
|
357
361
|
NEHotspotNetwork.fetchCurrent { [weak self] network in
|
|
358
362
|
self?.queue.async {
|
|
@@ -361,8 +365,15 @@ public final class GlassesHotspotNetwork {
|
|
|
361
365
|
if network?.ssid == ssid, let selected = self.selectBinding() {
|
|
362
366
|
self.bind(selected)
|
|
363
367
|
self.finishAssociation(address: selected.address, generation: gen)
|
|
368
|
+
} else if remaining > 0, network?.ssid != ssid,
|
|
369
|
+
self.reapplyPolicy.shouldReapply(applies: self.applies, pollsSinceApply: pollsSinceApply) {
|
|
370
|
+
// iOS reports the request applied even when its one scan missed the hotspot.
|
|
371
|
+
self.logger.info("HOTSPOT_JOIN reapply after_polls=\(pollsSinceApply)")
|
|
372
|
+
self.applyConfiguration(ssid: ssid, passphrase: passphrase, generation: gen, remaining: remaining)
|
|
364
373
|
} else if remaining > 0 {
|
|
365
|
-
self.queue.asyncAfter(deadline: .now() + 0.5) {
|
|
374
|
+
self.queue.asyncAfter(deadline: .now() + 0.5) {
|
|
375
|
+
self.waitForAddress(ssid: ssid, passphrase: passphrase, generation: gen, remaining: remaining - 1, pollsSinceApply: pollsSinceApply + 1)
|
|
376
|
+
}
|
|
366
377
|
} else {
|
|
367
378
|
let association = network == nil ? "unavailable" : (network?.ssid == ssid ? "matched" : "different")
|
|
368
379
|
self.finishJoin(.failure(LocalMediaError("Glasses hotspot has no verified Wi-Fi address (SSID=\(association), \(self.wifiDiagnostic()))")))
|