// 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<payloadLength; i++) {
|
|
data[i] -= (payloadLength - i) ^ key;
|
|
data[i] = (data[i] ^ (key ^ i));
|
|
}
|
|
|
|
b.set(data, 12)
|
|
|
|
let xor = b[0];
|
|
for (let i=1; i<length-1; i++)
|
|
xor ^= b[i];
|
|
|
|
b[length-1] = xor;
|
|
|
|
return b;
|
|
|
|
}
|
|
|