|
|
@@ -437,6 +437,11 @@ export const useBleStore = defineStore('ble', {
|
|
|
devices.set(d.deviceId, d)
|
|
|
foundCount++
|
|
|
console.log(`[BLE Scan] 发现设备 #${foundCount}: name=${name}, deviceId=${d.deviceId}, RSSI=${d.RSSI}`)
|
|
|
+ // advertisData为空的设备跳过,无法区分同名设备
|
|
|
+ if (!advertisDataHex) {
|
|
|
+ console.log(`[BLE Scan] 跳过无广播数据的设备: ${name || d.deviceId}`)
|
|
|
+ continue
|
|
|
+ }
|
|
|
const hit =
|
|
|
(deviceName && name === deviceName) ||
|
|
|
(namePrefix && name.startsWith(namePrefix)) ||
|
|
|
@@ -562,6 +567,7 @@ export const useBleStore = defineStore('ble', {
|
|
|
this._setState(BLE_STATE.READY_COMM)
|
|
|
s.reconnectCount = 0
|
|
|
} catch (e) {
|
|
|
+ console.log("蓝牙连接失败",e)
|
|
|
this._setState(BLE_STATE.DISCONNECTED)
|
|
|
this.device = null // 连接失败,清空 device 防止延迟回调误触发重连
|
|
|
try { await _invoke(uni.closeBLEConnection, { deviceId }) } catch (_) {}
|
|
|
@@ -576,7 +582,8 @@ export const useBleStore = defineStore('ble', {
|
|
|
/** 扫描 + 连接一步到位(支持 deviceId 直连优先,跳过扫描) */
|
|
|
async scanAndConnect(opt = {}) {
|
|
|
const { deviceId: directId, deviceName, advertisData: passedAdvertisData, ...restOpt } = opt
|
|
|
- console.log("连接opt",opt,directId,passedAdvertisData,restOpt)
|
|
|
+ console.log("连接opt",opt,directId,passedAdvertisData,restOpt,{ ...restOpt })
|
|
|
+
|
|
|
// 策略:如果已有 deviceId,先尝试直连(不扫描),失败后回退扫描
|
|
|
if (directId) {
|
|
|
try {
|
|
|
@@ -598,14 +605,35 @@ export const useBleStore = defineStore('ble', {
|
|
|
|
|
|
// 回退:扫描 + 连接
|
|
|
const scanOpt = { ...restOpt }
|
|
|
- if (deviceName) scanOpt.deviceName = deviceName
|
|
|
- const device = await this.startScan(scanOpt)
|
|
|
+
|
|
|
+ let device = null
|
|
|
+ if (passedAdvertisData) {
|
|
|
+ // 有 advertisData 时:不传 deviceName 做名称过滤(后端名与蓝牙广播名可能不一致)
|
|
|
+ // 扫描所有设备,再通过 advertisData 精确定位目标
|
|
|
+ scanOpt.returnAll = true
|
|
|
+ const devices = await this.startScan(scanOpt)
|
|
|
+ console.log(`[BLE scanAndConnect] 扫描到 ${devices.length} 个设备,目标 advertisData=${passedAdvertisData}`)
|
|
|
+ // 精确匹配 advertisData
|
|
|
+ device = devices.find(d => {
|
|
|
+ const hex = d._advertisDataHex || d.advertisData || ''
|
|
|
+ return hex === passedAdvertisData
|
|
|
+ })
|
|
|
+ if (!device) {
|
|
|
+ throw _err(BLE_ERROR.SCAN_FAIL, { msg: '未找到目标设备(advertisData不匹配)' })
|
|
|
+ }
|
|
|
+ console.log(`[BLE scanAndConnect] ✅ 通过advertisData匹配到设备: name=${device.name || device.localName}, deviceId=${device.deviceId}`)
|
|
|
+ } else {
|
|
|
+ // 无 advertisData 时按设备名过滤,返回第一个匹配设备
|
|
|
+ if (deviceName) scanOpt.deviceName = deviceName
|
|
|
+ device = await this.startScan(scanOpt)
|
|
|
+ }
|
|
|
+
|
|
|
await this.connectDevice(device.deviceId)
|
|
|
this.device.name = device.name || device.localName || ''
|
|
|
console.log("连接device._advertisDataHex",device._advertisDataHex)
|
|
|
// 存储 advertisData(hex 字符串):优先用传入的(后台 deviceCode),其次用扫描结果的 hex
|
|
|
// 注意:device.advertisData 是原始 ArrayBuffer,不能直接存储,需使用 _advertisDataHex
|
|
|
- this.device.advertisData = passedAdvertisData || device.advertisData || ''
|
|
|
+ this.device.advertisData = passedAdvertisData || device._advertisDataHex || device.advertisData || ''
|
|
|
return this.device
|
|
|
},
|
|
|
|
|
|
@@ -631,7 +659,8 @@ export const useBleStore = defineStore('ble', {
|
|
|
const s = _S()
|
|
|
const svcRes = await _invoke(uni.getBLEDeviceServices, { deviceId })
|
|
|
const services = svcRes.services || []
|
|
|
- const targetSvc = services.find(sv => _uuidEq(sv.uuid, s.config.serviceId))
|
|
|
+ const strict = s.config.strictUUID
|
|
|
+ const targetSvc = (strict && services.find(sv => _uuidEq(sv.uuid, s.config.serviceId)))
|
|
|
|| services.find(sv => sv.isPrimary)
|
|
|
|| services[0]
|
|
|
if (!targetSvc) throw _err(BLE_ERROR.SERVICE_NOT_FOUND)
|
|
|
@@ -642,9 +671,9 @@ export const useBleStore = defineStore('ble', {
|
|
|
})
|
|
|
const chars = charRes.characteristics || []
|
|
|
|
|
|
- const writeChar = chars.find(c => _uuidEq(c.uuid, s.config.writeCharId))
|
|
|
+ const writeChar = (strict && chars.find(c => _uuidEq(c.uuid, s.config.writeCharId)))
|
|
|
|| chars.find(c => c.properties && (c.properties.write || c.properties.writeNoResponse || c.properties.writeDefault))
|
|
|
- const notifyChar = chars.find(c => _uuidEq(c.uuid, s.config.notifyCharId))
|
|
|
+ const notifyChar = (strict && chars.find(c => _uuidEq(c.uuid, s.config.notifyCharId)))
|
|
|
|| chars.find(c => c.properties && (c.properties.notify || c.properties.indicate))
|
|
|
|
|
|
if (!writeChar) throw _err(BLE_ERROR.CHAR_NOT_FOUND, { msg: '未找到写特征' })
|