const resp = require('../util/resp') const noble = require('noble'); let inRange = {}; let blueDeviceList = [] let blueCharacteristics = [] let connectedCharacteristic = null; let on_data_callback = null; noble.on('discover', function (peripheral) { if(peripheral.addressType != 'public') { return; } inRange[peripheral.id] = { peripheral: peripheral }; var blueDevice = { 'id': peripheral.id, 'localName': peripheral.advertisement.localName, 'serviceUuids': JSON.stringify(peripheral.advertisement.serviceUuids), 'address': peripheral.address, 'addressType': peripheral.addressType, 'connectable': peripheral.connectable, 'rssi': peripheral.rssi, } blueDeviceList.push(blueDevice) explore(peripheral) }); function explore(peripheral) { peripheral.connect(error => { peripheral.discoverServices([], function (error, services) { for (let serviceIndex = 0; serviceIndex < services.length; serviceIndex++) { (function (service) { service.discoverCharacteristics([], function (error, characteristics) { for (let charIndex = 0; charIndex < characteristics.length; charIndex++) { let c = characteristics[charIndex]; let info = { id: peripheral.id, uuid: service.uuid, name: service.name, characteristic: { 'uuid': c.uuid, 'properties': c.properties } } blueCharacteristics.push(info) } }) })(services[serviceIndex]) } setTimeout(function () { peripheral.disconnect() }, 1000) }) }) } function merge_scan_result() { for (let i = 0; i < blueDeviceList.length; i++) { let device = blueDeviceList[i] device.characteristics = [] for (let j = 0; j < blueCharacteristics.length; j++) { let character = blueCharacteristics[j] if (device.id == character.id) { console.log(character) device.characteristics.push(character) } } } // console.log(blueDeviceList) return blueDeviceList } function connectAndSetUp(peripheral,server_uuid,characteristic_uuid) { peripheral.connect(error => { console.log('Connected to', peripheral.id); // specify the services and characteristics to discover const serviceUUIDs = [server_uuid]; const characteristicUUIDs = [characteristic_uuid]; peripheral.discoverSomeServicesAndCharacteristics( serviceUUIDs, characteristicUUIDs, onServicesAndCharacteristicsDiscovered ); }); peripheral.on('disconnect', () => console.log('disconnected')); } function onServicesAndCharacteristicsDiscovered(error, services, characteristics) { console.log('Discovered services and characteristics'); const echoCharacteristic = characteristics[0]; // data callback receives notifications echoCharacteristic.on('data', (data, isNotification) => { if (on_data_callback) { on_data_callback(data) } }); // subscribe to be notified whenever the peripheral update the characteristic echoCharacteristic.subscribe(error => { if (error) { console.error('Error subscribing to echoCharacteristic'); } else { console.log('Subscribed for echoCharacteristic notifications'); } }); connectedCharacteristic = echoCharacteristic } module.exports = { scan: function (resp_callback) { try { blueDeviceList = [] blueCharacteristics = [] setTimeout(() => { noble.stopScanning() resp_callback(resp.ok_resp(merge_scan_result())) }, 3000); noble.startScanning() } catch (e) { resp_callback(resp.fail_resp(e.message)) } }, connect: function (args, on_data_cb, resp_callback) { on_data_callback = on_data_cb; connectAndSetUp(inRange[args.id].peripheral,args.server_uuid,args.characteristic_uuid) }, write: function (msg, resp_callback) { try { const buffer = new Buffer(msg, 'utf-8'); if (connectedCharacteristic) { connectedCharacteristic.write(buffer); } } catch (e) { resp_callback(resp.fail_resp(e.message)) } } }