baseBleApi.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. var currentDevice = {};
  2. //ble设备
  3. var notifyService = {};
  4. //唤醒特征值
  5. var writeService = {};
  6. //写入服务
  7. var writeCharacteristic = {};
  8. //写入特征值
  9. var notifyCharacteristic = {};
  10. //唤醒特征值
  11. var onSendSuccessCallBack = undefined;
  12. //成功回调
  13. var onConnectCallback = undefined;
  14. // 链接回调
  15. var bleUtils = require('strUtils.js');
  16. var crc = require('crc.js');
  17. var isConnected = false;
  18. //是否已链接
  19. module.exports = {
  20. writeCommend: writeCommend,
  21. closeBLEConnection: closeBLEConnection
  22. // disConnect, disConnect,
  23. // openBluetoothAdapter: openBluetoothAdapter
  24. }
  25. /**
  26. * @param sendCommend 写入命令
  27. * @param deviceName 锁具名称
  28. * @param onSuccessCallBack 成功回调
  29. * @param onFailCallBack 返回失败回调
  30. * @param onCompleteCallBack 成功失败都会回调
  31. *
  32. * @param services 主服务serviceUUID
  33. * @param writeServiceUUID 写入服务UUID
  34. * @param notifyServiceUUID 唤醒服务UUID
  35. *
  36. * @param notifyCharacteristicUUID 唤醒特征值UUID
  37. * @param writeCharacteristicUUID 写入特征值UUID
  38. */
  39. function writeCommend(options) {
  40. var params = {};
  41. var defalt = {
  42. adviceId: "",
  43. sendCommend: "",
  44. onSuccessCallBack: function success(res) {},
  45. onFailCallBack: function success(res) {},
  46. onCompleteCallBack: function success(res) {},
  47. services: [],
  48. writeServiceUUID: "",
  49. notifyServiceUUID: "",
  50. notifyCharacteristicUUID: "",
  51. writeCharacteristicUUID: ""
  52. };
  53. params = Object.assign(defalt, options)
  54. // setConnectionStateChange(params.onFailCallBack)
  55. if (!setConnectionStateChange()) {
  56. openBluetoothAdapter(params);
  57. } else {
  58. // typeof str == 'string'
  59. sendCmd(params.sendCommend, params.onSuccessCallBack, params.onFailCallBack);
  60. }
  61. }
  62. /**
  63. * 初始化蓝牙适配器
  64. */
  65. function openBluetoothAdapter(params) {
  66. wx.openBluetoothAdapter({
  67. success: function (res) {
  68. console.log("初始化蓝牙适配器成功")
  69. console.log(res)
  70. startBluetoothDevicesDiscovery(params)
  71. },
  72. fail: function (res) {
  73. console.log("初始化蓝牙适配器失败")
  74. params.onFailCallBack(res.errMsg)
  75. console.log(res);
  76. return
  77. },
  78. complete: function (res) {
  79. console.log(res);
  80. }
  81. })
  82. }
  83. /**
  84. * 开始搜寻附近的蓝牙外围设备。注意,该操作比较耗费系统资源,请在搜索并连接到设备后调用 stop 方法停止搜索。
  85. * @ params services:['4asdga'],根据主ServiceUUID进行搜索特定蓝牙,提高搜索效率
  86. * 本ble设备主ServiceUUid: "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
  87. */
  88. var delayTimer;
  89. //停止循环获取tag
  90. var isFound =
  91. false
  92. function startBluetoothDevicesDiscovery(params, connectCallback) {
  93. if (
  94. typeof connectCallback ==
  95. 'undefined') {
  96. connectCallback =
  97. function (errMsg) {}
  98. }
  99. onConnectCallback = connectCallback;
  100. setTimeout(
  101. function () {
  102. if (isFound) {
  103. return;
  104. } else {
  105. console.log(
  106. "搜索设备超时");
  107. params.onFailCallBack(
  108. "搜索设备超时")
  109. stopBluetoothDevicesDiscovery();
  110. clearInterval(delayTimer)
  111. return
  112. }
  113. },
  114. 10000);
  115. wx.startBluetoothDevicesDiscovery({
  116. services: params.services,
  117. success: function (res) {
  118. console.log(res)
  119. console.log(
  120. "开启搜索成功")
  121. getBluetoothDevices(params)
  122. },
  123. fail: function (res) {
  124. console.log(
  125. "开启搜索失败")
  126. console.log(res)
  127. params.onFailCallBack(res)
  128. return
  129. },
  130. complete: function (res) {
  131. // complete
  132. console.log(res);
  133. }
  134. })
  135. //每隔一秒获取一次
  136. delayTimer = setInterval(
  137. function () {
  138. getBluetoothDevices(params)
  139. },
  140. 1000)
  141. }
  142. /**
  143. * 获取所有已发现的蓝牙设备,包括已经和本机处于连接状态的设备
  144. */
  145. function getBluetoothDevices(params) {
  146. wx.getBluetoothDevices({
  147. success: function (res) {
  148. console.log(
  149. "getBluetoothDevices");
  150. console.log(res.devices);
  151. for (
  152. var i =
  153. 0; i < res.devices.length; i++) {
  154. //忽略传入的deviceName大小写
  155. // isContains bleUtils
  156. var lockNameFinal = bleUtils.removeBytes(params.adviceId,
  157. ":")
  158. if (bleUtils.isContains(res.devices[i].name, lockNameFinal)) {
  159. console.log(
  160. "搜索到要链接的设备....")
  161. stopBluetoothDevicesDiscovery();
  162. isFound =
  163. true
  164. clearInterval(delayTimer)
  165. currentDevice = res.devices[i]
  166. createBLEConnection(params)
  167. }
  168. }
  169. },
  170. fail: function (res) {
  171. clearInterval(delayTimer)
  172. console.log(
  173. "没有搜索到要链接的设备....")
  174. console.log(res)
  175. params.onFailCallBack(res)
  176. stopBluetoothDevicesDiscovery();
  177. return
  178. }
  179. })
  180. }
  181. /**
  182. * 停止搜寻附近的蓝牙外围设备。请在确保找到需要连接的设备后调用该方法停止搜索。
  183. */
  184. function stopBluetoothDevicesDiscovery() {
  185. wx.stopBluetoothDevicesDiscovery({
  186. success: function (res) {
  187. console.log(res)
  188. }
  189. })
  190. }
  191. /**
  192. * 连接低功耗蓝牙设备
  193. */
  194. function createBLEConnection(params) {
  195. // setConnectionStateChange(params.onFailCallBack);
  196. setTimeout(
  197. function () {
  198. if (isConnected)
  199. return;
  200. console.log(
  201. "连接设备超时");
  202. params.onFailCallBack(
  203. "连接设备超时")
  204. return
  205. },
  206. 5000)
  207. wx.createBLEConnection({
  208. // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
  209. deviceId: currentDevice.deviceId +
  210. "",
  211. success: function (res) {
  212. console.log(res)
  213. console.log(
  214. `连接成功 : ${currentDevice.deviceId
  215. }`)
  216. isConnected =
  217. true
  218. getBLEDeviceServices(params);
  219. },
  220. fail: function (res) {
  221. console.log(res)
  222. params.onFailCallBack(res)
  223. console.log(
  224. `连接失败 : ${currentDevice.deviceId
  225. }`)
  226. }
  227. })
  228. }
  229. /**
  230. * closeBLEConnection
  231. * 断开与低功耗蓝牙设备的连接
  232. */
  233. function closeBLEConnection(deviceId) {
  234. wx.closeBLEConnection({
  235. deviceId: currentDevice.deviceId +
  236. "",
  237. success: function (res) {
  238. console.log(res)
  239. }
  240. })
  241. }
  242. /**
  243. *
  244. * 返回蓝牙是否正处于链接状态
  245. */
  246. function setConnectionStateChange(onFailCallback) {
  247. wx.onBLEConnectionStateChange(
  248. function (res) {
  249. // 该方法回调中可以用于处理连接意外断开等异常情况
  250. console.log(
  251. `device ${res.deviceId
  252. } state has changed, connected: ${res.connected
  253. }`);
  254. return res.connected;
  255. });
  256. }
  257. /**
  258. * 获取蓝牙设备所有 service(服务)
  259. * @params writeServiceUUID:ble设备所具有的写入服务UUID
  260. * @params notifyServiceUUID:ble设备具有的唤醒服务UUID
  261. */
  262. function getBLEDeviceServices(params) {
  263. wx.getBLEDeviceServices({
  264. // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
  265. deviceId: currentDevice.deviceId +
  266. "",
  267. success: function (res) {
  268. console.log(
  269. `获取服务成功 :`)
  270. console.log(
  271. 'device services:', res.services)
  272. for (
  273. var i =
  274. 0; i < res.services.length; i++) {
  275. if (res.services[i].uuid == params.writeServiceUUID) {
  276. writeService = res.services[i]
  277. }
  278. if (res.services[i].uuid == params.notifyServiceUUID) {
  279. notifyService = res.services[i]
  280. }
  281. }
  282. //获取
  283. getNotifyBLEDeviceCharacteristics(params);
  284. }
  285. })
  286. }
  287. /**
  288. * 获取蓝牙设备唤醒characteristic(特征值)
  289. */
  290. function getNotifyBLEDeviceCharacteristics(params) {
  291. wx.getBLEDeviceCharacteristics({
  292. // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
  293. deviceId: currentDevice.deviceId +
  294. "",
  295. // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
  296. serviceId: notifyService.uuid +
  297. "",
  298. success: function (res) {
  299. console.log(
  300. "唤醒特征值获取成功:")
  301. console.log(
  302. 'device getBLEDeviceCharacteristics:', res.characteristics)
  303. for (
  304. var i =
  305. 0; i < res.characteristics.length; i++) {
  306. if (res.characteristics[i].uuid == params.notifyCharacteristicUUID) {
  307. notifyCharacteristic = res.characteristics[i]
  308. }
  309. }
  310. // getWriteBLEDeviceCharacteristics();
  311. console.log(
  312. "唤醒特征值 :", notifyCharacteristic)
  313. getWriteBLEDeviceCharacteristics(params)
  314. }
  315. })
  316. }
  317. function getWriteBLEDeviceCharacteristics(params) {
  318. wx.getBLEDeviceCharacteristics({
  319. // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
  320. deviceId: currentDevice.deviceId +
  321. "",
  322. // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
  323. serviceId: writeService.uuid +
  324. "",
  325. success: function (res) {
  326. console.log(
  327. "写入特征值获取成功:")
  328. console.log(
  329. 'device getBLEDeviceCharacteristics:', res.characteristics)
  330. for (
  331. var i =
  332. 0; i < res.characteristics.length; i++) {
  333. if (res.characteristics[i].uuid == params.writeCharacteristicUUID) {
  334. writeCharacteristic = res.characteristics[i]
  335. }
  336. }
  337. console.log(
  338. "xieru :", writeCharacteristic)
  339. initNotifyListener(params);
  340. }
  341. })
  342. }
  343. /**
  344. *
  345. * 连接成功后,初始化回调监听
  346. *
  347. * 启用低功耗蓝牙设备特征值变化时的 notify 功能。注意:\
  348. * 必须设备的特征值支持notify才可以成功调用,具体参照 characteristic 的 properties 属性
  349. */
  350. function initNotifyListener(params) {
  351. wx.notifyBLECharacteristicValueChanged({
  352. deviceId: currentDevice.deviceId +
  353. "",
  354. serviceId: notifyService.uuid +
  355. "",
  356. characteristicId: notifyCharacteristic.uuid +
  357. "",
  358. state: true,
  359. success: function (res) {
  360. console.log(`开启监听成功${res.errMsg
  361. }`);
  362. setTimeout(
  363. function () {
  364. onConnectCallback('ok');
  365. // 连接成功后,初始化回调监听回调
  366. sendCmd(params.sendCommend, params.onSuccessCallBack, params.onFailCallBack);
  367. },
  368. 200);
  369. },
  370. fail: function (res) {
  371. console.log("开启监听失败" + res.errMsg);
  372. params.onFailCallBack("开启监听失败");
  373. }
  374. });
  375. onBLECharacteristicValueChange();
  376. }
  377. /**
  378. * 启用低功耗蓝牙设备特征值变化时的 notify 功能。注意:
  379. * 必须设备的特征值支持notify才可以成功调用,具体参照 characteristic 的 properties 属性
  380. */
  381. function onBLECharacteristicValueChange() {
  382. wx.onBLECharacteristicValueChange(
  383. function (res) {
  384. console.log(`characteristic ${res.characteristicId} has changed, now is ${bleUtils.arrayBuffer2HexString(res.value)}`);
  385. onSendSuccessCallBack(bleUtils.arrayBuffer2HexString(res.value));
  386. })
  387. }
  388. /**
  389. * 发送指令,不关心指令具体长度
  390. * @param commond 指令
  391. * @param onSuccess 指令执行成功回调
  392. */
  393. function sendCmd(commond, onSuccess, onFailCallback) {
  394. var sendCommonds = crc.getCRCCmd(commond);
  395. //对commond的CRC处理必须放在这里
  396. if (
  397. typeof onSuccess == 'undefined') {
  398. onSuccess =
  399. function (result) {}
  400. }
  401. onSendSuccessCallBack = onSuccess;
  402. sendCmds(sendCommonds, 0, onFailCallback);
  403. }
  404. /**
  405. *
  406. * 逐条发送指令
  407. */
  408. function sendCmds(commond, index, onFailCallback) {
  409. var itemCmd;
  410. var isLast =
  411. false;
  412. // 判断是否是最后一条
  413. if (commond.length > index + 40) {
  414. itemCmd = commond.substr(index, 40);
  415. } else {
  416. isLast = true;
  417. itemCmd = commond.substr(index);
  418. }
  419. writeCommendToBle(itemCmd,
  420. function (errMsg) {
  421. if (errMsg == 'ok' && !isLast) {
  422. // 发送成功并且不是最后一条时,执行下一条
  423. sendCmds(commond, index + 40);
  424. }
  425. }, onFailCallback)
  426. }
  427. // 向蓝牙中写入数据(ble蓝牙)(增加指纹)
  428. function writeCommendToBle(commonds, onSendCallback, onFailCallback) {
  429. var commond = commonds;
  430. console.log("commond :" + commond)
  431. let buffer = bleUtils.hexString2ArrayBuffer(commond);
  432. console.log(`执行指令:${bleUtils.arrayBuffer2HexString(buffer)
  433. }`);
  434. wx.writeBLECharacteristicValue({
  435. deviceId: currentDevice.deviceId +
  436. "",
  437. serviceId: writeService.uuid +
  438. '',
  439. characteristicId: writeCharacteristic.uuid +
  440. '',
  441. // 这里的value是ArrayBuffer类型
  442. value: buffer,
  443. success: function (res) {
  444. console.log('发送指令成功')
  445. console.log('writeBLECharacteristicValue success', res.errMsg)
  446. onSendCallback('ok');
  447. },
  448. fail: function (res) {
  449. console.log(`执行指令失败${res.errMsg }`);
  450. onFailCallback("执行指令失败");
  451. }
  452. })
  453. }