From 1749bd5e7fa959a022472defb8ba78c689c994af Mon Sep 17 00:00:00 2001 From: jdlugosz963 Date: Mon, 11 Dec 2023 15:31:44 +0100 Subject: Add initial ble-service. --- src/ble-service.ts | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 src/ble-service.ts (limited to 'src/ble-service.ts') diff --git a/src/ble-service.ts b/src/ble-service.ts new file mode 100644 index 0000000..f2a08a3 --- /dev/null +++ b/src/ble-service.ts @@ -0,0 +1,186 @@ +import BleManager, { + BleConnectPeripheralEvent, + BleDisconnectPeripheralEvent, + BleManagerDidUpdateValueForCharacteristicEvent, + BleScanCallbackType, + BleScanMatchMode, + BleScanMode, + Peripheral as PeripheralWithoutConnectInfo, +} from 'react-native-ble-manager'; +import { + EmitterSubscription, + NativeEventEmitter, + NativeModules, + PermissionsAndroid, + Platform, +} from 'react-native'; + +import Buffer from 'buffer'; + +export type Peripheral = PeripheralWithoutConnectInfo & { + connected?: boolean; + connecting?: boolean; +}; + +type Events = { + bleManagerStartSuccess: () => void | undefined; + bleManagerStartError: () => void | undefined; + bleManagerStopScan: () => void | undefined; + bleManagerStartScan: () => void | undefined; + bleManagerDiscoverPeripheral: (peripheral: Peripheral) => void | undefined; + bleManagerDisconnectPeripheral: ( + event: BleDisconnectPeripheralEvent, + ) => void | undefined; + bleManagerDidUpdateValueForCharacteristic: ( + event: BleManagerDidUpdateValueForCharacteristicEvent, + ) => void | undefined; + bleManagerConnectPeripheral: ( + event: BleConnectPeripheralEvent, + ) => void | undefined; +}; + +export default class BleService { + private _bleManagerModule = NativeModules.BleManager; + private _bleManagerEmitter = new NativeEventEmitter(this._bleManagerModule); + private _events: Events; + private _listeners: EmitterSubscription[]; + private _peripherals: Map; + + constructor() { + this._listeners = []; + this._events = {}; + this._peripherals = new Map(); + BleManager.start({showAlert: false}) + .then(() => { + this.runEvent(this._events.bleManagerStartSuccess); + console.debug('[BleService]: BleManager started.'); + }) + .catch((err: any) => { + this.runEvent(this._events.bleManagerStartError); + console.debug('[BleService]: BeManager could not be started.', err); + }); + this.handle_permissions(); + } + + setEvents(events: Events) { + this._events = events; + this.setupListiners(events); + } + + handle_permissions() { + // po requestach, jak sie zrobi .then() nastepnie gdy (resoult) cos zwroci to oznacza, że ma perma jak nie to nie ma. + if (Platform.OS === 'android') { + if (Platform.Version >= 31) + PermissionsAndroid.requestMultiple([ + PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN, + PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT, + ]); + else if (Platform.Version >= 23) + PermissionsAndroid.request( + PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, + ); + } + } + + scan() { + this.runEvent(this._events.bleManagerStartScan); + this.clearPeripherals(); + BleManager.scan([], 3, false, { + matchMode: BleScanMatchMode.Sticky, + scanMode: BleScanMode.LowLatency, + callbackType: BleScanCallbackType.AllMatches, + }) + .then(() => { + console.debug('[startScan] scan promise returned successfully.'); + }) + .catch((err: any) => { + console.error('[startScan] ble scan returned in error', err); + }); + } + + destroy() { + this.destroyListiners(); + } + + getPeripherals() { + return this._peripherals; + } + + connect(p: Peripheral) { + return BleManager.connect(p.id); + } + + async read(peripheral: Peripheral) { + await BleManager.requestMTU(peripheral.id, 512); + BleManager.startNotification( + peripheral.id, + '6e400001-b5a3-f393-e0a9-e50e24dcca9e', + '6e400003-b5a3-f393-e0a9-e50e24dcca9e', + ) + .then(a => { + // Success code + console.log('--------'); + console.log(a); + console.log('--------'); + }) + .catch(error => { + // Failure code + console.log(error); + }); + } + + private addPeripheral(p: Peripheral) { + this._peripherals.set(p.id, p); + } + + private clearPeripherals() { + this._peripherals = new Map(); + } + + private destroyListiners() { + for (const listener of this._listeners) { + if (listener) listener.remove(); + } + } + + private setupListiners(events: Events) { + this.destroyListiners(); + this._listeners = [ + this._bleManagerEmitter.addListener( + 'BleManagerDiscoverPeripheral', + peripheral => { + this.addPeripheral(peripheral); + this.runEvent(events.bleManagerDiscoverPeripheral, peripheral); + }, + ), + this._bleManagerEmitter.addListener('BleManagerStopScan', () => + this.runEvent(events.bleManagerStopScan), + ), + this._bleManagerEmitter.addListener( + 'BleManagerDisconnectPeripheral', + event => this.runEvent(events.bleManagerDisconnectPeripheral, event), + ), + this._bleManagerEmitter.addListener( + 'BleManagerDidUpdateValueForCharacteristic', + event => + this.runEvent( + events.bleManagerDidUpdateValueForCharacteristic, + event, + ), + ), + this._bleManagerEmitter.addListener( + 'BleManagerConnectPeripheral', + event => this.runEvent(events.bleManagerConnectPeripheral, event), + ), + ]; + } + + private runEvent( + event: CallableFunction | undefined, + ...optionalParams: any[] + ): void { + if (event) { + event(...optionalParams); + } + } +} -- cgit v1.2.3