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.

319 lines
10 KiB

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