fix(provision): treat WiFi join success by STA state, not internet ping
This commit is contained in:
@@ -124,7 +124,9 @@ class CaptiveServer {
|
||||
// 延迟执行,确保 HTTP 响应送达
|
||||
if (this._onConnect) {
|
||||
setTimeout(() => {
|
||||
this._onConnect(ssid, password || '');
|
||||
Promise.resolve(this._onConnect(ssid, password || '')).catch((e) => {
|
||||
log.error('http', '配网回调异常:', e.message);
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,8 +193,12 @@ function scanWifi() {
|
||||
}
|
||||
}
|
||||
|
||||
/** AP 切 STA 后等待网卡进入 connected 的最长时间(不依赖外网探测) */
|
||||
const CONNECT_WIFI_STA_WAIT_MS = 25_000;
|
||||
const CONNECT_WIFI_STA_POLL_MS = 1_000;
|
||||
|
||||
/**
|
||||
* 连接指定 WiFi
|
||||
* 连接指定 WiFi(配网场景:成功 = NM 显示 STA 已连上目标网,不要求一定能 ping 通 8.8.8.8)
|
||||
* @returns {{ success: boolean, error?: string }}
|
||||
*/
|
||||
function connectWifi(ssid, password) {
|
||||
@@ -205,15 +209,24 @@ function connectWifi(ssid, password) {
|
||||
try { run(`nmcli connection delete "${ssid}"`); } catch (_) {}
|
||||
|
||||
const pwdArg = password ? `password "${password}"` : '';
|
||||
run(`nmcli device wifi connect "${ssid}" ${pwdArg} ifname ${iface}`, 30000);
|
||||
run(`nmcli device wifi connect "${ssid}" ${pwdArg} ifname ${iface}`, 60000);
|
||||
|
||||
// 验证连通性
|
||||
sleep(3000);
|
||||
const deadline = Date.now() + CONNECT_WIFI_STA_WAIT_MS;
|
||||
while (Date.now() < deadline) {
|
||||
if (isWifiStaConnected()) {
|
||||
if (hasInternet()) {
|
||||
log.info('network', `WiFi 已连接: ${ssid}`);
|
||||
log.info('network', `WiFi 已连接且有外网: ${ssid}`);
|
||||
} else {
|
||||
log.warn(
|
||||
'network',
|
||||
`WiFi STA 已连接(${ssid}),暂未检测到外网;配网仍视为成功(内网/防火墙/国内 DNS 常见)`,
|
||||
);
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
return { success: false, error: '已连接但无法访问互联网' };
|
||||
sleep(CONNECT_WIFI_STA_POLL_MS);
|
||||
}
|
||||
return { success: false, error: '超时:网卡未进入已连接状态' };
|
||||
} catch (e) {
|
||||
log.error('network', `WiFi 连接失败: ${e.message}`);
|
||||
return { success: false, error: e.message };
|
||||
@@ -308,8 +321,12 @@ function isWifiStaConnected() {
|
||||
const out = run('nmcli -t -f DEVICE,TYPE,STATE,CONNECTION device');
|
||||
for (const line of out.split('\n')) {
|
||||
const parts = line.split(':');
|
||||
if (parts[0] === iface && parts[1] === 'wifi' && parts[2] === 'connected') {
|
||||
return parts[3] !== CON_NAME;
|
||||
const dev = (parts[0] || '').trim();
|
||||
const type = (parts[1] || '').trim();
|
||||
const state = (parts[2] || '').trim();
|
||||
const conn = (parts[3] || '').trim();
|
||||
if (dev === iface && type === 'wifi' && state === 'connected') {
|
||||
return conn !== CON_NAME;
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
@@ -163,6 +163,9 @@ class ProvisionManager extends EventEmitter {
|
||||
|
||||
this._stopAPServices();
|
||||
|
||||
// 关热点后射频/模式切换需要时间,立刻 connect 在部分板子上会失败
|
||||
await new Promise((r) => setTimeout(r, 2500));
|
||||
|
||||
const result = connectWifi(ssid, password);
|
||||
|
||||
if (result.success) {
|
||||
|
||||
Reference in New Issue
Block a user