@govincaresone/g-link
Version:
Porvide local hardware function to govin
347 lines (326 loc) • 14 kB
JavaScript
// const noble = require('@abandonware/noble');
// const Session = require('./session');
// const getUUID = id => {
// if (typeof id === 'number') return id.toString(16);
// if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(id)) {
// return id.split('-').join('');
// }
// return id;
// };
// class BLESession extends Session {
// constructor (socket) {
// super(socket);
// this._type = 'ble';
// this.peripheral = null;
// this.services = null;
// this.characteristics = {};
// this.notifyCharacteristics = {};
// this.scanningTimeId = null;
// this.reportedPeripherals = {};
// this.discoverListener = null;
// }
// async didReceiveCall (method, params, completion) {
// switch (method) {
// case 'discover':
// this.discover(params);
// completion(null, null);
// break;
// case 'connect':
// await this.connect(params);
// completion(null, null);
// break;
// case 'disconnect':
// await this.disconnect(params);
// completion(null, null);
// break;
// case 'write':
// completion(await this.write(params), null);
// this.repairNotifyAfterWrite();
// break;
// case 'read':
// completion(await this.read(params), null);
// break;
// case 'startNotifications':
// await this.startNotifications(params);
// completion(null, null);
// break;
// case 'stopNotifications':
// await this.stopNotifications(params);
// completion(null, null);
// break;
// case 'getServices':
// completion((this.services || []).map(service => service.uuid), null);
// break;
// case 'pingMe':
// completion('willPing', null);
// this.sendRemoteRequest('ping', null, result => {
// console.log(`Got result from ping: ${result}`);
// });
// break;
// default:
// throw new Error(`Method not found`);
// }
// }
// discover (params) {
// if (this.services) {
// throw new Error('cannot discover when connected');
// }
// const {filters} = params;
// // if (!Array.isArray(filters) || filters.length < 1) {
// // throw new Error('discovery request must include filters');
// // }
// // filters.forEach(item => {
// // const {services} = item;
// // if (!Array.isArray(services) || services.length < 1) {
// // throw new Error(`filter contains empty or invalid services list: ${item}`);
// // }
// // });
// if (this.scanningTimeId) {
// clearTimeout(this.scanningTimeId);
// }
// this.reportedPeripherals = {};
// noble.startScanning([], true);
// this.discoverListener = peripheral => {
// this.onAdvertisementReceived(peripheral, filters);
// };
// noble.on('discover', this.discoverListener);
// }
// onAdvertisementReceived (peripheral, filters) {
// const {advertisement} = peripheral;
// if (advertisement) {
// const finded = (filters || []).find(filter => {
// const {name, namePrefix, services, manufacturerData} = filter;
// if (name && name !== advertisement.localName) return false;
// if (namePrefix && advertisement.localName.indexOf(namePrefix) !== 0) return false;
// if (services && !services.every(service => {
// if (!advertisement.serviceUuids) return false;
// return advertisement.serviceUuids.indexOf(getUUID(service)) !== -1;
// })) return false;
// if (manufacturerData && advertisement.manufacturerData) {
// if (manufacturerData.length !== advertisement.manufacturerData.length) {
// return false;
// }
// if (!manufacturerData.every((data, i) => advertisement.manufacturerData[i] === data)) {
// return false;
// }
// }
// return !!advertisement.localName;
// });
// if (finded) {
// this.reportedPeripherals[peripheral.id] = peripheral;
// this.sendRemoteRequest('didDiscoverPeripheral', {
// peripheralId: peripheral.id,
// name: advertisement.localName,
// rssi: peripheral.rssi
// });
// if (!this.scanningTimeId) {
// this.scanningTimeId = setTimeout(() => {
// this.scanningTimeId = null;
// noble.stopScanning();
// if (this.discoverListener) {
// noble.removeListener('discover', this.discoverListener);
// }
// }, 1000);
// }
// }
// }
// }
// connect (params) {
// return new Promise((resolve, reject) => {
// if (this.peripheral && this.peripheral.state === 'connected') {
// return reject(new Error('already connected to peripheral'));
// }
// const {peripheralId} = params;
// const peripheral = this.reportedPeripherals[peripheralId];
// if (!peripheral) {
// return reject(new Error(`invalid peripheral ID: ${peripheralId}`));
// }
// if (this.scanningTimeId) {
// clearTimeout(this.scanningTimeId);
// this.scanningTimeId = null;
// noble.stopScanning();
// }
// try {
// peripheral.connect(error => {
// if (error) {
// return reject(new Error(error));
// }
// peripheral.discoverAllServicesAndCharacteristics((err, services) => {
// if (err) {
// return reject(new Error(error));
// }
// this.services = services;
// this.peripheral = peripheral;
// resolve();
// });
// });
// peripheral.on('disconnect', () => {
// this.disconnect();
// });
// } catch (err) {
// reject(err);
// }
// });
// }
// bleWriteData (characteristic, withResponse, data) {
// return new Promise((resolve, reject) => {
// characteristic.write(data, !withResponse, err => {
// if (err) return reject(err);
// resolve();
// });
// });
// }
// async write (params) {
// try {
// const {message, encoding, withResponse} = params;
// const buffer = Buffer.from(message, encoding);
// const characteristic = await this.getEndpoint('write request', params, 'write');
// for (let i = 0; i < buffer.length; i += 20) {
// await this.bleWriteData(characteristic, withResponse, buffer.slice(i, 20));
// }
// return buffer.length;
// } catch (err) {
// return new Error(`Error while attempting to write: ${err.message}`);
// }
// }
// bleReadData (characteristic, encoding = 'base64') {
// return new Promise((resolve, reject) => {
// characteristic.read((err, data) => {
// if (err) {
// return reject(err);
// }
// resolve(data.toString(encoding));
// });
// });
// }
// async read (params) {
// try {
// const characteristic = await this.getEndpoint('read request', params, 'read');
// const readedData = await this.bleReadData(characteristic);
// const {startNotifications} = params;
// if (startNotifications) {
// await this.startNotifications(params, characteristic);
// }
// return readedData;
// } catch (err) {
// console.log('Error while attempting to read: ', err);
// return new Error(`Error while attempting to read: ${err.message}`);
// }
// }
// async startNotifications (params, characteristic) {
// if (!characteristic || characteristic.properties.indexOf('notify') === -1) {
// characteristic = await this.getEndpoint('startNotifications request', params, 'notify');
// }
// const uuid = getUUID(characteristic.uuid);
// if (!this.notifyCharacteristics[uuid]) {
// this.notifyCharacteristics[uuid] = characteristic;
// characteristic.subscribe();
// }
// if (!characteristic._events || !characteristic._events.data) {
// characteristic.on('data', data => {
// this.onValueChanged(characteristic, data);
// });
// }
// }
// async stopNotifications (params) {
// console.log('stopNotifications !!!');
// const characteristic = await this.getEndpoint('stopNotifications request', params, 'notify');
// characteristic.unsubscribe();
// characteristic.removeAllListeners('data');
// delete this.notifyCharacteristics[getUUID(characteristic.uuid)];
// }
// notify (characteristic, notify) {
// return new Promise((resolve, reject) => {
// characteristic.notify(notify, err => {
// if (err) return reject(err);
// resolve();
// });
// });
// }
// // noble bug: After write, characteristic object will change
// repairNotifyAfterWrite () {
// for (const id in this.notifyCharacteristics) {
// const characteristic = this.notifyCharacteristics[id];
// const {_peripheralId, _serviceUuid, uuid} = characteristic;
// const currentCharacteristic = noble._characteristics[_peripheralId][_serviceUuid][uuid];
// if (characteristic !== currentCharacteristic) {
// currentCharacteristic._events = characteristic._events;
// this.notifyCharacteristics[id] = currentCharacteristic;
// }
// }
// }
// async stopAllNotifications () {
// for (const id in this.notifyCharacteristics) {
// await this.notify(this.notifyCharacteristics[id], false);
// this.notifyCharacteristics[id].removeAllListeners('data');
// }
// }
// onValueChanged (characteristic, data) {
// const params = {
// serviceId: characteristic._serviceUuid,
// characteristicId: characteristic.uuid,
// encoding: 'base64',
// message: data.toString('base64')
// };
// this.sendRemoteRequest('characteristicDidChange', params);
// }
// getEndpoint (errorText, params, type) {
// return new Promise((resolve, reject) => {
// if (!this.peripheral || this.peripheral.state !== 'connected') {
// return reject(`Peripheral is not connected for ${errorText}`);
// }
// let service;
// let serviceUuid;
// let {serviceId, characteristicId} = params;
// characteristicId = getUUID(characteristicId);
// if (this.characteristics[characteristicId]) {
// return resolve(this.characteristics[characteristicId]);
// }
// if (serviceId) {
// serviceId = getUUID(serviceId);
// service = this.services.find(item => item.uuid === serviceId);
// } else {
// service = this.services[0];
// serviceUuid = service.uuid;
// }
// if (!service) {
// reject(`Could not determine service UUID for ${errorText}`);
// }
// service.discoverCharacteristics([characteristicId], (err, characteristics) => {
// if (err) {
// console.warn(err);
// return reject(`could not find characteristic ${characteristicId} on service ${serviceUuid}`);
// }
// const characteristic = characteristics.find(item => item.properties.includes(type));
// if (characteristic) {
// this.characteristics[characteristicId] = characteristic;
// resolve(characteristic);
// } else {
// reject(`failed to collect ${type} characteristic from service`);
// }
// });
// });
// }
// disconnect () {
// if (this.peripheral && this.peripheral.state === 'connected') {
// this.peripheral.disconnect();
// }
// }
// dispose () {
// this.disconnect();
// super.dispose();
// this.stopAllNotifications();
// this.socket = null;
// this.peripheral = null;
// this.services = null;
// this.characteristics = null;
// this.scanningTimeId = null;
// this.reportedPeripherals = null;
// this.notifyCharacteristics = null;
// if (this.discoverListener) {
// noble.removeListener('discover', this.discoverListener);
// this.discoverListener = null;
// }
// }
// }
// module.exports = BLESession;