nobleWrapper.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. const resp = require('../util/resp')
  2. const noble = require('noble');
  3. let inRange = {};
  4. let blueDeviceList = []
  5. let blueCharacteristics = []
  6. const ECHO_SERVICE_UUID = 'ec00';
  7. const ECHO_CHARACTERISTIC_UUID = 'ec0e';
  8. let connectedCharacteristic = null;
  9. let on_data_callback = null;
  10. noble.on('discover', function (peripheral) {
  11. inRange[peripheral.id] = {
  12. peripheral: peripheral
  13. };
  14. var blueDevice = {
  15. 'id': peripheral.id,
  16. 'localName': peripheral.advertisement.localName,
  17. 'serviceUuids': JSON.stringify(peripheral.advertisement.serviceUuids),
  18. 'address': peripheral.address,
  19. 'addressType': peripheral.addressType,
  20. 'connectable': peripheral.connectable,
  21. 'rssi': peripheral.rssi,
  22. }
  23. blueDeviceList.push(blueDevice)
  24. explore(peripheral)
  25. });
  26. function explore(peripheral) {
  27. peripheral.connect(error => {
  28. peripheral.discoverServices([], function (error, services) {
  29. for (let serviceIndex = 0; serviceIndex < services.length; serviceIndex++) {
  30. (function (service) {
  31. service.discoverCharacteristics([], function (error, characteristics) {
  32. for (let charIndex = 0; charIndex < characteristics.length; charIndex++) {
  33. let c = characteristics[charIndex];
  34. let info = {
  35. id: peripheral.id,
  36. uuid: service.uuid,
  37. name: service.name,
  38. characteristic: {
  39. 'uuid': c.uuid,
  40. 'properties': c.properties
  41. }
  42. }
  43. blueCharacteristics.push(info)
  44. }
  45. })
  46. })(services[serviceIndex])
  47. }
  48. setTimeout(function () {
  49. peripheral.disconnect()
  50. }, 1000)
  51. })
  52. })
  53. }
  54. function merge_scan_result() {
  55. for (let i = 0; i < blueDeviceList.length; i++) {
  56. let device = blueDeviceList[i]
  57. device.characteristics = []
  58. for (let j = 0; j < blueCharacteristics.length; j++) {
  59. let character = blueCharacteristics[j]
  60. if (device.id === character.id) {
  61. device.characteristics.push(character)
  62. }
  63. }
  64. }
  65. return blueDeviceList
  66. }
  67. function connectAndSetUp(peripheral) {
  68. peripheral.connect(error => {
  69. console.log('Connected to', peripheral.id);
  70. // specify the services and characteristics to discover
  71. const serviceUUIDs = [ECHO_SERVICE_UUID];
  72. const characteristicUUIDs = [ECHO_CHARACTERISTIC_UUID];
  73. peripheral.discoverSomeServicesAndCharacteristics(
  74. serviceUUIDs,
  75. characteristicUUIDs,
  76. onServicesAndCharacteristicsDiscovered
  77. );
  78. });
  79. peripheral.on('disconnect', () => console.log('disconnected'));
  80. }
  81. function onServicesAndCharacteristicsDiscovered(error, services, characteristics) {
  82. console.log('Discovered services and characteristics');
  83. const echoCharacteristic = characteristics[0];
  84. // data callback receives notifications
  85. echoCharacteristic.on('data', (data, isNotification) => {
  86. if (on_data_callback) {
  87. on_data_callback(data)
  88. }
  89. });
  90. // subscribe to be notified whenever the peripheral update the characteristic
  91. echoCharacteristic.subscribe(error => {
  92. if (error) {
  93. console.error('Error subscribing to echoCharacteristic');
  94. } else {
  95. console.log('Subscribed for echoCharacteristic notifications');
  96. }
  97. });
  98. connectedCharacteristic = echoCharacteristic
  99. }
  100. module.exports = {
  101. scan: function (resp_callback) {
  102. try {
  103. blueDeviceList = []
  104. blueCharacteristics = []
  105. setTimeout(() => {
  106. noble.stopScanning()
  107. resp_callback(resp.ok_resp(merge_scan_result()))
  108. }, 2000);
  109. noble.startScanning()
  110. } catch (e) {
  111. resp_callback(resp.fail_resp(e.message))
  112. }
  113. },
  114. connect: function (id, on_data_cb, resp_callback) {
  115. on_data_callback = on_data_cb;
  116. connectAndSetUp(inRange[id].peripheral)
  117. },
  118. write: function (msg, resp_callback) {
  119. try {
  120. const buffer = new Buffer(msg, 'utf-8');
  121. if (connectedCharacteristic) {
  122. connectedCharacteristic.write(buffer);
  123. }
  124. } catch (e) {
  125. resp_callback(resp.fail_resp(e.message))
  126. }
  127. }
  128. }