bike-ali/utils/blufi/xBlufi-ali-impl.js
2024-12-17 10:20:53 +08:00

560 lines
18 KiB
JavaScript

let tempTimer = 0;
let client = null;
let util = null;
let mDeviceEvent = null;
let crypto = null;
let md5 = null;
let aesjs = null;
const timeOut = 20; //超时时间
let mac_id;
var timeId = "";
let sequenceControl = 0;
let sequenceNumber = -1;
let self = {
data: {
deviceId: null,
isConnected: false,
failure: false,
value: 0,
desc: "请耐心等待...",
isChecksum: true,
isEncrypt: true,
flagEnd: false,
defaultData: 1,
ssidType: 2,
passwordType: 3,
meshIdType: 3,
deviceId: "",
ssid: "",
uuid: "",
serviceId: "",
password: "",
meshId: "",
processList: [],
result: [],
service_uuid: "00FF", // 简化的服务 UUID
characteristic_write_uuid: "FF01", // 简化的写特征值 UUID
characteristic_read_uuid: "FF02", // 简化的读特征值 UUID
customData: null,
md5Key: 0
}
};
// 工具函数
function Utf8ArrayToStr(buffer) {
var out, i, len, c;
var char2, char3;
var array = new Uint8Array(buffer);
out = "";
len = array.length;
i = 0;
while(i < len) {
c = array[i++];
switch(c >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
out += String.fromCharCode(c);
break;
case 12: case 13:
char2 = array[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}
return out;
}
function string2buffer(str) {
var bytes = new Array();
for(var i = 0; i < str.length; i++) {
var c = str.charCodeAt(i);
var s = parseInt(c).toString(2);
if(c >= parseInt('000080', 16) && c <= parseInt('0007FF', 16)) {
var af = '';
for(var j = 0; j < (11 - s.length); j++) {
af += '0';
}
af += s;
var n1 = parseInt('110' + af.substring(0, 5), 2);
var n2 = parseInt('110' + af.substring(5), 2);
if(n1 > 127) n1 -= 256;
if(n2 > 127) n2 -= 256;
bytes.push(n1);
bytes.push(n2);
} else if(c >= parseInt('000800', 16) && c <= parseInt('00FFFF', 16)) {
var af = '';
for(var j = 0; j < (16 - s.length); j++) {
af += '0';
}
af += s;
var n1 = parseInt('1110' + af.substring(0, 4), 2);
var n2 = parseInt('10' + af.substring(4, 10), 2);
var n3 = parseInt('10' + af.substring(10), 2);
if(n1 > 127) n1 -= 256;
if(n2 > 127) n2 -= 256;
if(n3 > 127) n3 -= 256;
bytes.push(n1);
bytes.push(n2);
bytes.push(n3);
} else {
bytes.push(c & 0xff);
}
}
let array = [];
for(let i = 0; i < bytes.length; i++) {
array[i] = bytes[i];
}
let array_int8 = Uint8Array.from(array);
return array_int8.buffer;
}
function buf2hex(buffer) {
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
function buf2string(buffer) {
var arr = Array.prototype.map.call(new Uint8Array(buffer), x => x);
var str = '';
for(var i = 0; i < arr.length; i++) {
str += String.fromCharCode(arr[i]);
}
return str;
}
function writeCutomsData(deviceId, serviceId, characteristicId, data) {
console.log("开始发送数据:", data);
// 确保数据是字符串类型
const dataString = String(data);
// 创建 ArrayBuffer
const buffer = new ArrayBuffer(dataString.length);
const dataView = new DataView(buffer);
// 写入数据
for(let i = 0; i < dataString.length; i++) {
dataView.setUint8(i, dataString.charCodeAt(i));
}
my.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: characteristicId,
value: buffer,
success: function(res) {
console.log("数据发送成功");
},
fail: function(res) {
console.error("数据发送失败", res);
}
});
}
function writeDeviceRouterInfoStart(deviceId, serviceId, characteristicId, data) {
console.log('ssid:', data.ssid);
console.log('password:', data.password);
let ssid = string2buffer(data.ssid);
let password = string2buffer(data.password);
my.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: characteristicId,
value: ssid,
success: function(res) {
console.log("SSID发送成功");
// 发送密码
setTimeout(() => {
my.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: characteristicId,
value: password,
success: function(res) {
console.log("密码发送成功");
},
fail: function(res) {
console.log("密码发送失败", res);
}
});
}, 200);
},
fail: function(res) {
console.log("SSID发送失败", res);
}
});
}
function init() {
let mOnFire = require("./other/onfire.js");
mDeviceEvent = require("./xBlufi.js");
util = require("./util.js");
crypto = require("./crypto/crypto-dh.js");
md5 = require("./crypto/md5.min.js");
aesjs = require("./crypto/aes.js");
// 监听蓝牙连接状态变化
my.onBLEConnectionStateChanged(function(res) {
let obj = {
'type': mDeviceEvent.XBLUFI_TYPE.TYPE_STATUS_CONNECTED,
'result': res.connected,
'data': res
};
mDeviceEvent.notifyDeviceMsgEvent(obj);
});
// 监听开始搜索蓝牙设备
mDeviceEvent.listenStartDiscoverBle(true, function(options) {
if(options.isStart) {
console.log("开始搜索蓝牙设备");
my.closeBluetoothAdapter({
success: function() {
my.openBluetoothAdapter({
success: function() {
let devicesList = [];
my.onBluetoothDeviceFound(function(res) {
console.log("发现设备:", res);
const devices = res.devices[0];
if(devices && devices.deviceId) {
const deviceName = devices.name || devices.deviceName || '';
console.log("设备名称:", deviceName);
if(deviceName.startsWith('BBLE')) {
let isNotExist = true;
for(let i = 0; i < devicesList.length; i++) {
if(devices.deviceId === devicesList[i].deviceId) {
devicesList[i].RSSI = devices.RSSI;
isNotExist = false;
break;
}
}
if(isNotExist) {
devicesList.push({
deviceId: devices.deviceId,
name: deviceName,
localName: deviceName,
mac: deviceName.substring(5),
RSSI: devices.RSSI || 0,
advertisData: devices.advertisData ? buf2hex(devices.advertisData) : ''
});
}
let obj = {
'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS,
'result': true,
'data': devicesList
};
mDeviceEvent.notifyDeviceMsgEvent(obj);
}
}
});
my.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true,
interval: 0,
powerLevel: 'high',
success: function(res) {
console.log("开始搜索成功");
let obj = {
'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
'result': true,
'data': res
};
mDeviceEvent.notifyDeviceMsgEvent(obj);
devicesList = [];
setTimeout(() => {
my.stopBluetoothDevicesDiscovery({
success: function(res) {
console.log("搜索完成,发现设备:", devicesList);
let obj = {
'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP,
'result': true,
'data': devicesList
};
mDeviceEvent.notifyDeviceMsgEvent(obj);
}
});
}, 5000);
}
});
}
});
}
});
} else {
my.stopBluetoothDevicesDiscovery({
success: function(res) {
let obj = {
'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP,
'result': true,
'data': res
};
mDeviceEvent.notifyDeviceMsgEvent(obj);
}
});
}
});
// 监听连接蓝牙设备
mDeviceEvent.listenConnectBle(true, function(options) {
if(options.connect) {
console.log("开始连接设备:", options.deviceId);
my.connectBLEDevice({
deviceId: options.deviceId,
success: function(res) {
console.log("连接设备成功");
setTimeout(() => {
my.getBLEDeviceServices({
deviceId: options.deviceId,
success: function(res) {
console.log("获取服务列表成功:", res.services);
const targetService = res.services.find(
service => service.serviceId.toLowerCase() === self.data.service_uuid.toLowerCase()
);
if(targetService) {
console.log("找到目标服务:", targetService.serviceId);
my.getBLEDeviceCharacteristics({
deviceId: options.deviceId,
serviceId: targetService.serviceId,
success: function(res) {
console.log("获取特征值列表成功:", res.characteristics);
my.notifyBLECharacteristicValueChange({
deviceId: options.deviceId,
serviceId: targetService.serviceId,
characteristicId: self.data.characteristic_read_uuid,
state: true,
success: function() {
console.log("特征值通知开启成功");
},
fail: function(error) {
console.error("特征值通知开启失败:", error);
}
});
},
fail: function(error) {
console.error("获取特征值列表失败:", error);
}
});
} else {
console.error("未找到目标服务");
}
},
fail: function(error) {
console.error("获取服务列表失败:", error);
}
});
}, 1000);
},
fail: function(error) {
console.error("连接设备失败:", error);
}
});
} else {
console.log("断开设备连接:", options.deviceId);
my.disconnectBLEDevice({
deviceId: options.deviceId,
success: function() {
console.log("断开连接成功");
},
fail: function(error) {
console.error("断开连接失败:", error);
}
});
}
});
// 监听初始化蓝牙设备
mDeviceEvent.listenInitBleEsp32(true, function(options) {
sequenceControl = 0;
sequenceNumber = -1;
self.data.deviceId = options.deviceId;
mac_id = options.deviceId;
setTimeout(() => {
my.getBLEDeviceServices({
deviceId: options.deviceId,
success: function(res) {
let services = res.services;
for(let service of services) {
if(service.serviceId === self.data.service_uuid) {
my.getBLEDeviceCharacteristics({
deviceId: options.deviceId,
serviceId: service.serviceId,
success: function(res) {
let characteristics = res.characteristics;
for(let characteristic of characteristics) {
if(characteristic.characteristicId === self.data.characteristic_write_uuid) {
self.data.serviceId = service.serviceId;
self.data.uuid = characteristic.characteristicId;
my.notifyBLECharacteristicValueChange({
deviceId: options.deviceId,
serviceId: service.serviceId,
characteristicId: self.data.characteristic_read_uuid,
state: true,
success: function() {
writeCutomsData(self.data.deviceId, self.data.service_uuid, self.data.characteristic_write_uuid, "get_fw");
setTimeout(() => {
my.setBLEMTU({
deviceId: self.data.deviceId,
mtu: 212,
success: function(res) {
console.log("设置MTU成功");
}
});
}, 1000);
}
});
my.onBLECharacteristicValueChange(function(res) {
let value = Utf8ArrayToStr(res.value);
if(value.indexOf("wifi_ok") !== -1) {
mDeviceEvent.notifyDeviceMsgEvent({
'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECT_ROUTER_RESULT,
'result': true,
'data': {
'progress': 100,
'ssid': ""
}
});
} else if(value.indexOf("wifi_err") !== -1) {
mDeviceEvent.notifyDeviceMsgEvent({
'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECT_ROUTER_RESULT,
'result': false,
'data': {
'progress': 0,
'ssid': ""
}
});
} else {
let obj = {
'type': mDeviceEvent.XBLUFI_TYPE.TYPE_RECIEVE_CUSTON_DATA,
'result': true,
'data': value
};
mDeviceEvent.notifyDeviceMsgEvent(obj);
}
});
}
}
}
});
}
}
}
});
}, 2000);
});
// 监听发送路由器信息
mDeviceEvent.listenSendRouterSsidAndPassword(true, function(options) {
self.data.password = options.password;
self.data.ssid = options.ssid;
writeDeviceRouterInfoStart(self.data.deviceId, self.data.service_uuid, self.data.characteristic_write_uuid, self.data);
});
// 修改 listenSendCustomData 监听器
// 修改发送自定义数据的处理
mDeviceEvent.listenSendCustomData(true, function(options) {
console.log("准备发送自定义数据:", options.customData);
if(!options.customData) {
console.error("自定义数据为空");
return;
}
my.getBLEDeviceServices({
deviceId: mac_id,
success: function(res) {
console.log("获取服务列表:", res.services);
const services = res.services;
// 查找匹配的服务
const targetService = services.find(service => {
const serviceId = service.serviceId.toLowerCase();
return serviceId.includes(self.data.service_uuid.toLowerCase());
});
if(targetService) {
console.log("找到目标服务:", targetService.serviceId);
my.getBLEDeviceCharacteristics({
deviceId: mac_id,
serviceId: targetService.serviceId,
success: function(res) {
console.log("获取特征值列表:", res.characteristics);
// 查找匹配的写特征值
const writeCharacteristic = res.characteristics.find(char => {
const charId = char.characteristicId.toLowerCase();
return charId.includes(self.data.characteristic_write_uuid.toLowerCase());
});
if(writeCharacteristic) {
console.log("找到写特征值:", writeCharacteristic.characteristicId);
// 发送数据
const buffer = string2buffer(options.customData);
my.writeBLECharacteristicValue({
deviceId: mac_id,
serviceId: targetService.serviceId,
characteristicId: writeCharacteristic.characteristicId,
value: buffer,
success: function(res) {
console.log("数据发送成功");
mDeviceEvent.notifyDeviceMsgEvent({
'type': mDeviceEvent.XBLUFI_TYPE.TYPE_SEND_CUSTOM_DATA_RESULT,
'result': true,
'data': options.customData
});
},
fail: function(error) {
console.error("数据发送失败:", error);
mDeviceEvent.notifyDeviceMsgEvent({
'type': mDeviceEvent.XBLUFI_TYPE.TYPE_SEND_CUSTOM_DATA_RESULT,
'result': false,
'data': error
});
}
});
} else {
console.error("未找到写特征值");
}
},
fail: function(error) {
console.error("获取特征值失败:", error);
}
});
} else {
console.error("未找到目标服务");
}
},
fail: function(error) {
console.error("获取服务列表失败:", error);
}
});
});
}
module.exports = {
init: init
};