小程序蓝牙通信例子
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

637 lines
16 KiB

// 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;
}