// pages/lanyatest/lanyatest.js var longUtil = require('./../../utils/long.js'); Page({ /** * 页面的初始数据 */ data: { info:"未初始化蓝牙适配器", deviceName:"yxwl01680000004895", connectedDeviceId:"", deviceId:"", services:"", mtuSize:512, servicesUUID:"000018f0-0000-1000-8000-00805f9b34fb", notifyUUID:"00002af0-0000-1000-8000-00805f9b34fb", writeUUID:"00002af1-0000-1000-8000-00805f9b34fb", serviceId:"", notifyCharacteristicsId:"", writeCharacteristicsId: "", userTelephone:"13028878230", userPassword:"130288", pwd:"12344321", openLockType:2, sendmsg:"8989415B017BC796C6F8001DA0B0AAB7AFABB1B6B9B1BAB7B0BE8989A9AB8BABBE80EEEEE2E2E6E6EFE4", systemInfo:{}, }, lanyatest1(event){ var that = this; wx.getSystemInfo({ success: function (res) { console.log(res.model) console.log(res.pixelRatio) console.log(res.windowWidth) console.log(res.windowHeight) console.log(res.language) console.log(res.version) console.log(res.platform) console.log(res.environment) that.setData({ systemInfo:res }); } }) checkWechatVersion(that.data.systemInfo) wx.openBluetoothAdapter({ success: function (res) { console.log('初始化蓝牙适配器成功') //页面日志显示 that.setData({ info: '初始化蓝牙适配器成功' }) }, fail: function (res) { console.log('请打开蓝牙和定位功能') that.setData({ info: '请打开蓝牙和定位功能' }) } }) }, lanyatest2(event){ var that = this; wx.getBluetoothAdapterState({ success: function (res) { //打印相关信息 console.log(JSON.stringify(res.errMsg) + "\n蓝牙是否可用:" + res.available); that.setData({ info: JSON.stringify(res.errMsg) +"\n蓝牙是否可用:" + res.available }) }, fail: function (res) { //打印相关信息 console.log(JSON.stringify(res.errMsg) + "\n蓝牙是否可用:" + res.available); that.setData({ info: JSON.stringify(res.errMsg) + "\n蓝牙是否可用:" + res.available }) } }) }, lanyatest3(event){ var that = this; wx.startBluetoothDevicesDiscovery({ services: [that.data.servicesUUID], //如果填写了此UUID,那么只会搜索出含有这个UUID的设备 success: function (res) { that.setData({ info: "搜索设备" + JSON.stringify(res), }) console.log('搜索设备返回' + JSON.stringify(res)) } }) }, lanyatest4(event){ var that = this; var pos; wx.getBluetoothDevices({ success: function (res) { for (var i = 0; i < res.devices.length; i++) { pos = that.data.deviceName.indexOf(res.devices[i].name); if(pos != -1) { that.setData({ connectedDeviceId: res.devices[i].deviceId }) console.log('设备号:' + res.devices[i].name + " Mac地址: " + that.data.connectedDeviceId + " pos: " + pos + "\n") break; } } that.setData({ info: "设备列表\n" + JSON.stringify(res.devices), devices: res.devices }) console.log('搜设备数目:' + res.devices.length) console.log('设备信息:\n' + JSON.stringify(res.devices)+"\n") } }) }, lanyaconnect(event){ var that = this; wx.createBLEConnection({ deviceId: that.data.connectedDeviceId, success: function (res) { console.log('调试信息:' + res.errMsg); that.setData({ info: "MAC地址:" + event.currentTarget.id + ' 调试信息:' + res.errMsg, }) if (that.data.systemInfo.platform == 'android') { wx.setBLEMTU({ deviceId: that.data.connectedDeviceId, mtu:that.data.mtuSize, success:(res)=>{ console.log("setBLEMTU success >> " + JSON.stringify(res)) }, fail:(res)=>{ console.log("setBLEMTU fail >> " + JSON.stringify(res)) } }) } }, fail: function () { console.log("连接失败"); }, }) }, lanyatest6(event){ var that = this; wx.stopBluetoothDevicesDiscovery({ success: function (res) { console.log("停止搜索" + JSON.stringify(res.errMsg)); that.setData({ info: "停止搜索" + JSON.stringify(res.errMsg), }) } }) }, lanyatest7(event){ var that = this; wx.getBLEDeviceServices({ // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取 deviceId: that.data.connectedDeviceId, success: function (res) { console.log('services UUID:\n', JSON.stringify(res.services)); for (var i = 0; i < res.services.length; i++) { console.log("第"+(i+1) + "个UUID:" + res.services[i].uuid+"\n") } that.setData({ services: res.services, info: JSON.stringify(res.services), }) } }) }, lanyatest8(event){ var that = this; var myUUID = toPlatformString(that.data.systemInfo, that.data.servicesUUID);//具有写、通知属性的服务uuid console.log(' UUID: ' + myUUID + " mac: " + that.data.connectedDeviceId) wx.getBLEDeviceCharacteristics({ // 这里的 deviceId 需要在上面的接口中获取 deviceId: that.data.connectedDeviceId, // 这里的 serviceId 需要在上面的 接口中获取 serviceId: myUUID, success: function (res) { console.log("%c getBLEDeviceCharacteristics", "color:red;"); for (var i = 0; i < res.characteristics.length; i++) { console.log('特征值:' + res.characteristics[i].uuid) if (res.characteristics[i].properties.notify) { console.log("notifyServicweId:", myUUID); console.log("notifyCharacteristicsId:", res.characteristics[i].uuid); that.setData({ notifyServicweId: myUUID, notifyCharacteristicsId: that.data.notifyUUID,//手动设置notifyCharacteristicsId为这个UUID,为了方便写死在这里 }) } if (res.characteristics[i].properties.write) { console.log("writeServicweId:", myUUID); console.log("writeCharacteristicsId:", res.characteristics[i].uuid); that.setData({ writeServicweId: myUUID, //writeCharacteristicsId: res.characteristics[i].uuid, writeCharacteristicsId: that.data.writeUUID,//手动设置writeCharacteristicsId为这个UUID,为了方便写死在这里 }) } } console.log('device getBLEDeviceCharacteristics:', res.characteristics); that.setData({ msg: JSON.stringify(res.characteristics), }) }, fail: function () { console.log("fail"); }, }) }, lanyatest9(event){ var that = this; var notifyServicweId = toPlatformString(that.data.systemInfo, that.data.servicesUUID); //具有写、通知属性的服务uuid var notifyCharacteristicsId = toPlatformString(that.data.systemInfo, that.data.notifyCharacteristicsId); console.log("启用notify的serviceId", notifyServicweId); console.log("启用notify的notifyCharacteristicsId", notifyCharacteristicsId); wx.notifyBLECharacteristicValueChange({ state: true, // 启用 notify 功能 deviceId: that.data.connectedDeviceId, // 这里的 serviceId 就是that.data.servicesUUID serviceId: notifyServicweId, characteristicId: notifyCharacteristicsId, success: function (res) { console.log('notifyBLECharacteristicValueChange success', res.errMsg) var msg = '启动notify:' + res.errMsg that.setData({ info: msg }) }, fail: function () { console.log('启动notify:' + res.errMsg); }, }) }, lanyatest10(event){ var that = this; console.log("开始接收数据"); wx.onBLECharacteristicValueChange(function (res) { console.log("characteristicId:" + res.characteristicId) console.log("serviceId: " + res.serviceId) console.log("deviceId: " + res.deviceId) console.log("Length: " + res.value.byteLength) console.log("hex value: " + ab2hex(res.value)) that.setData({ info: that.data.info + ab2hex(res.value) }) }) }, lanyatest11(event){ var that = this //var hex = that.data.sendmsg //要发送的信息 var myUUID = toPlatformString(that.data.systemInfo, that.data.servicesUUID); //具有写、通知属性的服务uuid var writeCharId = toPlatformString(that.data.systemInfo, that.data.writeCharacteristicsId); //console.log('要发送的信息是:'+hex) //var typedArray1 = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) { // return parseInt(h, 16) //})) //console.log(typedArray1) var typedArray = packData(that.data.userTelephone, that.data.userPassword, that.data.pwd, that.data.openLockType) console.log(typedArray) wx.writeBLECharacteristicValue({ deviceId: that.data.connectedDeviceId, serviceId: myUUID, characteristicId: writeCharId, // 这里的value是ArrayBuffer类型 value: typedArray.buffer, success: function (res) { console.log('写入成功', res.errMsg) }, fail(res){ console.log('写入失败', res.errMsg) } }) }, //获取输入框的数据 getmsg(event){ this.setData({ sendmsg:event.detail.value }) }, lanyatest12(event){ var that = this; wx.closeBLEConnection({ deviceId: that.data.connectedDeviceId, success: function (res) { that.setData({ connectedDeviceId: "", }) console.log('断开蓝牙设备成功:' + res.errMsg) }, fail:function(res){ console.log('断开蓝牙设备失败:' + res.errMsg) } }) }, }) function toPlatformString(systemInfo, str) { if (systemInfo.platform == 'android') return str.toLowerCase(); else if (systemInfo.platform == 'ios') return str.toUpperCase(); else return str; } /** * 版本比较 */ function versionCompare (ver1, ver2) { //版本比较 // console.log("ver1" + ver1 + 'ver2' + ver2); var version1pre = parseFloat(ver1) var version2pre = parseFloat(ver2) var version1next = parseInt(ver1.replace(version1pre + ".", "")) var version2next = parseInt(ver2.replace(version2pre + ".", "")) if (version1pre > version2pre) return true else if (version1pre < version2pre) return false else { if (version1next > version2next) return true else return false } } /** * 微信版本检测 * Android从微信 6.5.7 开始支持,iOS从微信 6.5.6 开始支持 */ function checkWechatVersion(systemInfo) { if (systemInfo.platform == 'android' && versionCompare('6.5.7', systemInfo.version)) { wx.showModal({ title: '提示', content: '当前微信版本过低,请更新至最新版本体验', showCancel: false }) }else if (systemInfo.platform == 'ios' && versionCompare('6.5.6', systemInfo.version)) { wx.showModal({ title: '提示', content: '当前微信版本过低,请更新至最新版本体验', showCancel: false }) } } function Uint8ArrayToString(fileData){ var dataString = ""; for (var i = 0; i < fileData.length; i++) { dataString += String.fromCharCode(fileData[i]); } return dataString } // 微信官方给的ArrayBuffer转十六进制示例 function ab2hex(buffer) { var hexArr = Array.prototype.map.call( new Uint8Array(buffer), function (bit) { return ('00' + bit.toString(16)).slice(-2) } ) return hexArr.join(','); } //转成可展会的文字 function hexCharCodeToStr(hexCharCodeStr) { var trimedStr = hexCharCodeStr.trim(); var rawStr = trimedStr.substr(0, 2).toLowerCase() === '0x' ? trimedStr.substr(2) : trimedStr; var len = rawStr.length; var curCharCode; var resultStr = []; for (var i = 0; i < len; i = i + 2) { curCharCode = parseInt(rawStr.substr(i, 2), 16); resultStr.push(String.fromCharCode(curCharCode)); } return resultStr.join(''); } //转换成需要的格式 function buf2string(buffer) { var arr = Array.prototype.map.call(new Uint8Array(buffer), x => x) return arr.map((char, i) => { return String.fromCharCode(char); }).join(''); } function stringToUint8Array(str){ let arr = []; for (let i = 0, j = str.length; i < j; ++i) { arr.push(str.charCodeAt(i)); } let tmpUint8Array = new Uint8Array(arr); return tmpUint8Array } function decodeHexNibble(c) { if (c >= 48 && c <= 57) { return c - 48; } else if (c >= 65 && c <= 70) { return c - 65 + 10; } else { return c >= 97 && c <= 102 ? c - 97 + 10 : -1; } } function decodeHexByte(s, pos) { let hi = decodeHexNibble(s.charCodeAt(pos)); let lo = decodeHexNibble(s.charCodeAt(pos + 1)); return ((hi << 4) + lo); } function hexStringToBytesWithPadding(str, byteLen, padding) { let len = str.length let length = 2 * byteLen if (length >= len && (length & 1) == 0) { if (length == 0) { return [0]; } else { //let buffer = new ArrayBuffer(length >>> 1); //let bytes = new Uint8Array(buffer); let bytes = new Uint8Array(length >>> 1); for(let i = 0; i < len; i += 2) { bytes[i >>> 1] = decodeHexByte(str, i); } for(let i = 0; i < byteLen-len/2; i++) bytes[len/2+i] = padding; return bytes; } } else return [0]; } function hexStringToBytes(str) { let s = str; if(s.length < 12) { let tmp = 12-s.length for(let i = 0; i< tmp; i++) s = "0" + s; } else s = str.substr(s.length-12, s.length); let start = 0 let length = s.length if (length >= 0 && (length & 1) == 0) { if (length == 0) { return new byte[0]; } else { let bytes = new Uint8Array(length >>> 1); for(let i = 0; i < length; i += 2) { bytes[i >>> 1] = decodeHexByte(s, start + i); } return bytes; } } else return [0]; } function packData(userTelephone, userPassword, pwd, openLockType) { let cmd = 0x41 let ut = stringToUint8Array(userTelephone) let up = stringToUint8Array(userPassword) let p = hexStringToBytesWithPadding(pwd, 10, 0xff) let length = 1+11+6+10+1 let b = new Uint8Array(length) b[0] = cmd b.set(ut, 1) b.set(up, 12) b.set(p, 18) b[28] = openLockType console.log(b) return packMsg(0x41, b, length) } function packMsg(cmd, data, payloadLength) { let length = 13 + payloadLength //let buffer = new ArrayBuffer(length); let b = new Uint8Array(length); b[0] = 0x89; b[1] = 0x89; b[2] = cmd; let timestamp = new Date().getTime(); let ts = timestamp.toString(16) let t = hexStringToBytes(ts) b.set(t, 4) b[3] = b[9]; b[10] = (payloadLength>>8)&0xff; b[11] = payloadLength & 0xff; let key = b[3]; for (let i=0; i