SEC_Warehouse/utils/ble/modules/wifi.js

103 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { writeA7Payload } from '../core/packet'
import { waitForProtocolState } from '../core/stateWait'
const WIFI_FINAL_STATE_CODES = Object.freeze([1, 2, 3])
/**
* 校验 WiFi 入参,规则来源于 profile.wifi。
*/
function validateWifi(profile, ssid, password) {
const errors = []
if (!ssid || ssid.length > profile.wifi.maxSsidLength) {
errors.push(`SSID 长度需在 1-${profile.wifi.maxSsidLength} 之间`)
}
if (password.length < profile.wifi.minPasswordLength || password.length > profile.wifi.maxPasswordLength) {
errors.push(`密码长度需在 ${profile.wifi.minPasswordLength}-${profile.wifi.maxPasswordLength} 之间`)
}
const invalidChars = profile.wifi.invalidChars || []
if (invalidChars.some((char) => ssid.includes(char))) {
errors.push(`SSID 不能包含特殊字符: ${invalidChars.join(' ')}`)
}
if (errors.length) {
throw new Error(errors.join(''))
}
}
/** 校验鉴权状态,未完成密钥匹配则抛出异常。 */
function requireAuthorized(ble) {
const state = ble.getState()
if (!state.auth || state.auth.keyMatched !== true) {
throw new Error('请先完成密钥鉴权,再发送 WiFi 配置')
}
}
/**
* WiFi 配网模块:负责打包发送 ssid|password并等待 STATE 回执。
* 使用前必须先完成密钥鉴权。
* @param {object} ble createBleCore 实例
*/
export function createWifiModule(ble) {
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, Number(ms) || 0))
}
const log = (...args) => { try { console.debug('[BLE][WiFi]', ...args) } catch (e) {} }
/**
* 发送WiFi配网指令。
* 将 ssid|password 按 A7 分包写入 UUID_WIFI等待 STATE 回执判定结果。
* @param {string} ssid WiFi名称
* @param {string} password WiFi密码
* @param {object} options
* @param {number} options.timeout 等待状态回执超时(ms)默认12000
* @param {number} options.preDelayMs 写入前延迟(ms)ED713 默认120ms
* @param {number} options.packetInterval 分包写入间隔(ms)
* @returns {{ success: boolean, stateCode: number }} stateCode=3 表示连接成功
*/
async function configureWifi(ssid, password, options = {}) {
const profile = ble.getProfile()
const s = String(ssid || '').trim()
const p = String(password || '').trim()
validateWifi(profile, s, p)
requireAuthorized(ble)
const { wifi } = ble.getState().characteristics
if (!wifi || !wifi.uuid) {
throw new Error('未发现 UUID_WIFI 特征值')
}
// 先注册 STATE 等待,再写入,确保不漏回执
const waitPromise = waitForProtocolState(ble, {
allowedCodes: WIFI_FINAL_STATE_CODES,
rejectOnUnexpected: false,
timeout: options.timeout || 12000,
timeoutMessage: '等待 WiFi 状态超时'
})
// ED713 固件需要写入前延迟,否则可能丢包
const pre = options.preDelayMs ?? (profile.id === 'ED713' ? 120 : 0)
if (pre) {
log('preDelay before WiFi write(ms)=', pre)
await delay(pre)
}
log('write WiFi start', { service: ble.getState().serviceId, char: wifi.uuid })
const sent = await writeA7Payload(ble, wifi.uuid, `${s}|${p}`, profile.packet, {
packetInterval: Number(options.packetInterval) || 0
})
log('write WiFi done, packets=', sent)
const code = Number((await waitPromise).stateCode)
log('STATE(final) received for WiFi=', code)
// STATE=3 表示 WiFi 连接成功
return { success: code === 3, stateCode: code }
}
return { configureWifi, requireAuthorized }
}