fix: retry macOS robot hotspot scans
This commit is contained in:
@@ -10,6 +10,7 @@ const LOCATION_AUTHORIZED_ALWAYS = 3;
|
||||
const LOCATION_AUTHORIZED_WHEN_IN_USE = 4;
|
||||
const CORE_WLAN_PERMISSION_DENIED = -3930;
|
||||
const CORE_WLAN_UNSUPPORTED = -3903;
|
||||
const SCAN_RETRY_DELAY_MS = 250;
|
||||
|
||||
type StableReason = 'unsupported' | 'permission_denied' | 'scan_failed' | 'connect_failed';
|
||||
type ObjcId = unknown;
|
||||
@@ -21,6 +22,36 @@ interface WorkerCandidate {
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
export interface MacosScanNetwork {
|
||||
ssid: string | null;
|
||||
rssi: number;
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
export function scanMacosCandidatesWithRetry(
|
||||
readNetworks: () => MacosScanNetwork[],
|
||||
currentSsid: string | null,
|
||||
waitBeforeRetry: () => void,
|
||||
): WorkerCandidate[] {
|
||||
let networks = readNetworks();
|
||||
if (networks.length === 0 || networks.every((network) => !network.ssid)) {
|
||||
waitBeforeRetry();
|
||||
networks = readNetworks();
|
||||
}
|
||||
if (networks.length > 0 && networks.every((network) => !network.ssid)) {
|
||||
throw new RobotHotspotAdapterError('permission_denied');
|
||||
}
|
||||
return networks.flatMap((network): WorkerCandidate[] => {
|
||||
if (!network.open || !network.ssid) return [];
|
||||
return [{
|
||||
ssid: network.ssid,
|
||||
signalPercent: Math.max(0, Math.min(100, Math.round((network.rssi + 100) * 2))),
|
||||
connected: currentSsid === network.ssid,
|
||||
open: true,
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
type WorkerRequest = { id: number; operation: 'scan' } | { id: number; operation: 'connect'; ssid: string };
|
||||
type WorkerResponse = { id: number; ok: true; result: WorkerCandidate[] | { ssid: string } } | { id: number; ok: false; reason: StableReason };
|
||||
|
||||
@@ -219,13 +250,16 @@ async function runCoreWlanWorker(): Promise<void> {
|
||||
return withPool(() => {
|
||||
const wifi = wifiInterface('scan');
|
||||
const current = stringValue(sendId(wifi, selectors.ssid));
|
||||
return scanNetworks('scan').flatMap((network): WorkerCandidate[] => {
|
||||
if (!sendSupportsSecurity(network, selectors.supportsSecurity, 0)) return [];
|
||||
const ssid = stringValue(sendId(network, selectors.ssid));
|
||||
if (!ssid) return [];
|
||||
const rssi = Number(sendLong(network, selectors.rssiValue));
|
||||
return [{ ssid, signalPercent: Math.max(0, Math.min(100, Math.round((rssi + 100) * 2))), connected: current === ssid, open: true }];
|
||||
});
|
||||
const readNetworks = (): MacosScanNetwork[] => scanNetworks('scan').map((network) => ({
|
||||
ssid: stringValue(sendId(network, selectors.ssid)),
|
||||
rssi: Number(sendLong(network, selectors.rssiValue)),
|
||||
open: sendSupportsSecurity(network, selectors.supportsSecurity, 0),
|
||||
}));
|
||||
return scanMacosCandidatesWithRetry(
|
||||
readNetworks,
|
||||
current,
|
||||
() => { Atomics.wait(pollSleep, 0, 0, SCAN_RETRY_DELAY_MS); },
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user