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.

359 lines
12 KiB

1 year ago
  1. import * as t from "./tools"
  2. const app = getApp();
  3. const WXAPI = require('../request')
  4. /*
  5. import { HTTP } from "../server";
  6. */
  7. /**
  8. * 蓝牙工具类
  9. * 封装小程序蓝牙流程方法
  10. * 处理事件通信
  11. */
  12. class BLEHandler {
  13. constructor(blename, emitter) {
  14. this.blename = blename //厂家自定义的蓝牙设备名称
  15. this.emitter = emitter
  16. // if(manufactureId==201){
  17. // this.readCharacteristicId = "0000FFF0-0000-1000-8000-00805F9B34FB"; //能从硬件返回的信息中自动提取
  18. // this.writeCharacteristicId = "0000FFF2-0000-1000-8000-00805F9B34FB"; //能从硬件返回的信息中自动提取
  19. // this.notifyCharacteristicId = "0000FFF1-0000-1000-8000-00805F9B34FB"; //能从硬件返回的信息中自动提取
  20. // this.deviceId = ""; //蓝牙Mac地址
  21. // this.serviceId = "0000FFF3-0000-1000-8000-00805F9B34FB";//具体的serviceId要自己根据硬件提供设置。
  22. // }else{
  23. this.readCharacteristicId = ""; //能从硬件返回的信息中自动提取
  24. this.writeCharacteristicId = "00002af1-0000-1000-8000-00805f9b34fb"; //能从硬件返回的信息中自动提取
  25. this.notifyCharacteristicId = "00002af0-0000-1000-8000-00805f9b34fb"; //能从硬件返回的信息中自动提取
  26. this.deviceId = ""; //蓝牙Mac地址
  27. this.serviceId = "000018f0-0000-1000-8000-00805f9b34fb"; //具体的serviceId要自己根据硬件提供设置。
  28. // }
  29. this.receivePacket = [];
  30. this.recPktLength = 0;
  31. this.recPktOffset = 0;
  32. }
  33. async openAdapter() {
  34. let [err, res] = await t._openAdapter.call(this);
  35. if (err != null) {
  36. this.emitter.emit("channel", {
  37. type: "connect",
  38. data: "未打开适配器"
  39. })
  40. return false;
  41. }
  42. return true
  43. }
  44. async startSearch() {
  45. let [err, res] = await t._startSearch.call(this);
  46. if (err != null) {
  47. return;
  48. }
  49. this.emitter.emit("channel", {
  50. type: "connect",
  51. data: "正在连接中..."
  52. })
  53. }
  54. async onBluetoothFound() {
  55. let [err, res] = await t._onBluetoothFound.call(this);
  56. if (err != null) {
  57. this.emitter.emit("channel", {
  58. type: "connect",
  59. data: "未找到设备"
  60. })
  61. return false;
  62. }
  63. return true
  64. }
  65. async getBluetoothDevices() {
  66. let [err, res] = await t._getBluetoothDevices.call(this);
  67. if (err != null) {
  68. this.emitter.emit("channel", {
  69. type: "connect",
  70. data: "未找到设备"
  71. })
  72. return false;
  73. }
  74. return true
  75. }
  76. async stopSearchBluetooth() {
  77. let [err, res] = await t._stopSearchBluetooth.call(this);
  78. if (err != null) {
  79. return;
  80. }
  81. }
  82. async connectBlue() {
  83. let [err, res] = await t._connectBlue.call(this);
  84. if (err != null) {
  85. return;
  86. }
  87. }
  88. async setBLEMTU() {
  89. let [err, res] = await t._setBLEMTU.call(this);
  90. if (err != null) {
  91. return;
  92. }
  93. }
  94. async getBLEServices() {
  95. let [err, res] = await t._getBLEServices.call(this);
  96. if (err != null) {
  97. return;
  98. }
  99. }
  100. async getCharacteristics() {
  101. let [err, res] = await t._getCharacteristics.call(this);
  102. if (err != null) {
  103. this.emitter.emit("channel", {
  104. type: "connect",
  105. data: "无法订阅特征值"
  106. })
  107. // 取消连接
  108. this.closeBLEConnection()
  109. this.closeBLEAdapter()
  110. wx.setStorageSync("bluestatus", "");
  111. return false;
  112. }
  113. this.emitter.emit("channel", {
  114. type: "connect",
  115. data: "蓝牙已连接"
  116. })
  117. wx.setStorageSync("bluestatus", "on");
  118. return true
  119. }
  120. async notifyBLECharacteristicValueChange() {
  121. let [err, res] = await t._notifyBLECharacteristicValueChange.call(this);
  122. if (err != null) {
  123. return;
  124. }
  125. }
  126. async closeBLEConnection() {
  127. let [err, res] = await t._closeBLEConnection.call(this);
  128. if (err != null) {
  129. return;
  130. }
  131. }
  132. async closeBLEAdapter() {
  133. let [err, res] = await t._closeBLEAdapter.call(this);
  134. if (err != null) {
  135. return;
  136. }
  137. }
  138. async sentOrder(cmd, payload,timestamp, callback) {
  139. let data = t._sentOrder(cmd, payload,timestamp)
  140. console.log("-- 发送数据:", data)
  141. let arrayBuffer = new Uint8Array(data).buffer;
  142. let [err, res] = await t._writeBLECharacteristicValue.call(this, arrayBuffer)
  143. if (err != null) {
  144. var data1 = {
  145. success: false,
  146. data: err
  147. }
  148. callback(data1)
  149. return false
  150. }
  151. var data1 = {
  152. success: true,
  153. data: res
  154. }
  155. callback(data1)
  156. console.log("数据发送成功!")
  157. return true
  158. }
  159. // 打开蓝牙适配器状态监听
  160. onBLEConnectionStateChange() {
  161. wx.onBLEConnectionStateChange(res => {
  162. // 该方法回调中可以用于处理连接意外断开等异常情况
  163. if (!res.connected) {
  164. this.closeBLEAdapter()
  165. wx.setStorageSync("bluestatus", "");
  166. this.emitter.emit("channel", {
  167. type: "connect",
  168. data: "蓝牙已断开"
  169. })
  170. }
  171. }, err => {
  172. console.log('err', err)
  173. })
  174. }
  175. // 收到设备推送的notification
  176. onBLECharacteristicValueChange() {
  177. wx.onBLECharacteristicValueChange(res => {
  178. //let arrbf = new Uint8Array(res.value)
  179. //console.log(`收到硬件数据反馈!命令码为:${arrbf[2]}`)
  180. //if (this._checkData(arrbf)) {
  181. //}
  182. let arrbf = new Uint8Array(res.value)
  183. if (arrbf[0] == 0x89 && arrbf[1] == 0x89) {
  184. let dataLength = ((arrbf[10] << 8) & 0xff00) + (arrbf[11] & 0x00ff)
  185. this.recPktLength = 13 + dataLength
  186. this.receivePacket = new Uint8Array(this.recPktLength)
  187. this.recPktOffset = 0
  188. console.log("开始接收数据:length= " + arrbf.length + " data= " + arrbf)
  189. this.receivePacket.set(arrbf, this.recPktOffset)
  190. this.recPktOffset += arrbf.length;
  191. if (this.recPktOffset == this.recPktLength) {
  192. this.getReceivePacket(this.receivePacket)
  193. }
  194. } else {
  195. console.log("继续接收数据:length= " + arrbf.length + " data= " + arrbf)
  196. this.receivePacket.set(arrbf, this.recPktOffset)
  197. this.recPktOffset += arrbf.length;
  198. if (this.recPktOffset == this.recPktLength) {
  199. this.getReceivePacket(this.receivePacket)
  200. }
  201. }
  202. })
  203. }
  204. /*
  205. _uploadInfo(message) {
  206. console.log("-- 准备数据同步!", this._mapToArray(message))
  207. let bleorder = wx.getStorageSync("bleorder");
  208. let blecabinet = wx.getStorageSync("blecabinet")
  209. HTTP({
  210. url: "cabinet/uploadBlueData",
  211. methods: "post",
  212. data: {
  213. cabinetQrCode: blecabinet,
  214. order: bleorder,
  215. message: this._mapToArray(message)
  216. }
  217. }).then(res => {
  218. console.log("✔ 数据同步成功!")
  219. }, err => {
  220. console.log('✘ 数据同步失败', err)
  221. })
  222. }
  223. */
  224. _mapToArray(arrbf) {
  225. let arr = []
  226. arrbf.map(item => {
  227. arr.push(item)
  228. })
  229. return arr
  230. }
  231. // 校验数据正确性
  232. _checkData(arrbf) {
  233. let packetLen = arrbf.length;
  234. console.log("接收数据:" + arrbf)
  235. // 校验帧头帧尾
  236. if (arrbf[0] != 0x89 || arrbf[1] != 0x89) {
  237. console.log('不是该设备返回的包')
  238. return false
  239. }
  240. if (packetLen < 14) {
  241. console.log("包长太短,不是该设备返回的包");
  242. return false;
  243. }
  244. let dataLength = ((arrbf[10] << 8) & 0xff00) + (arrbf[11] & 0x00ff);
  245. if (dataLength != (packetLen - 13)) {
  246. let calLen = packetLen - 13;
  247. console.log("✘ 数据长度错误: " + dataLength + " is not " + calLen);
  248. return false;
  249. }
  250. //校验包
  251. let check = arrbf[0];
  252. for (let i = 1; i < packetLen - 1; i++)
  253. check ^= arrbf[i];
  254. if (check != arrbf[packetLen - 1]) {
  255. console.log("crc校验错误,请重发." + check);
  256. return false;
  257. }
  258. console.log('✔ 数据校验成功,接收完整!')
  259. return true
  260. }
  261. getReceivePacket(arrbf) {
  262. let that = this
  263. let packetLen = arrbf.length;
  264. console.log("接收数据:" + arrbf)
  265. // 校验帧头帧尾
  266. if (arrbf[0] != 0x89 || arrbf[1] != 0x89) {
  267. console.log('不是该设备返回的包')
  268. return [0];
  269. }
  270. if (packetLen < 14) {
  271. console.log("包长太短,不是该设备返回的包");
  272. return [0];
  273. }
  274. let dataLength = ((arrbf[10] << 8) & 0xff00) + (arrbf[11] & 0x00ff);
  275. if (dataLength != (packetLen - 13)) {
  276. let calLen = packetLen - 13;
  277. console.log("✘ 数据长度错误: " + dataLength + " is not " + calLen);
  278. return [0];
  279. }
  280. //校验包
  281. let check = arrbf[0];
  282. for (let i = 1; i < packetLen - 1; i++)
  283. check ^= arrbf[i];
  284. if (check != arrbf[packetLen - 1]) {
  285. console.log("crc校验错误,请重发." + check);
  286. return [0];
  287. }
  288. //数据解密
  289. let key = arrbf[3];
  290. let data_offset = 12;
  291. let result = new Uint8Array(dataLength)
  292. for (let i = 0; i < dataLength; i++) {
  293. result[i] = arrbf[i + data_offset];
  294. result[i] = (result[i] ^ (key ^ i));
  295. result[i] += (dataLength - i) ^ key;
  296. }
  297. console.log('✔ 数据校验成功,接收完整! packet= ' + arrbf)
  298. if (result[0] == 25 && result[result.length - 1] == 2) { //蓝牙录入指纹02,设备返回指纹ID
  299. app.globalData.fingerprintId = result[22]
  300. }
  301. if (result[0] == 25 && (result[result.length - 1] == 3 || result[result.length - 1] == 2 || result[result.length - 1] == 1)) { //蓝牙录入指纹01
  302. app.globalData.backdata = result[result.length - 1]
  303. }
  304. if (result[0] == 83 && result[1] == 1) {
  305. app.globalData.stop29 = true
  306. }
  307. if (result[0] == 49 && result[1] == 1) { //蓝牙开锁
  308. app.globalData.openlock = result[1]
  309. }
  310. console.log('解密明文 result= ' + result)
  311. // switch (arrbf[2]) {
  312. // case 0x53:
  313. // case 0x13:
  314. // case 0x58:
  315. // this.bleRspRecord(arrbf)
  316. // break;
  317. // }
  318. return result;
  319. }
  320. bleRspRecord(val) {
  321. var array = []
  322. val.forEach(element => {
  323. array.push(element)
  324. });
  325. var data = {
  326. code: "ble/deviceReport",
  327. data: {
  328. value: array,
  329. deviceNum: app.globalData.deviceNum
  330. }
  331. }
  332. console.log(app.globalData.deviceNum,data)
  333. WXAPI.sendCommand(data).then(res => {
  334. })
  335. }
  336. }
  337. export default BLEHandler