import { BleErrorCode } from 'react-native-ble-plx'; import { ProbeEmitter } from './ProbeEmitter'; import delay from './delay'; import { createErrorFromCode, createErrorFromBleError, SFPToolboxErrorCode } from '../../error/error'; import { base64ToHex } from '../../parsing/binary'; import LocalLogger from '../LocalLogger'; export class BluetoothProbeEmitter extends ProbeEmitter { static WRITE_TRANSACTION_ID = 'write-transaction-'; static MONITOR_TRANSACTION_ID = 'monitor-transaction-'; static SERVICE_UUID = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'; static WRITE_CHARACTERISTIC_UUID = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'; static READ_CHARACTERISTIC_UUID = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'; static TRANSACTION_COUNT = 0; static STOP_COMMAND_PAYLOAD = 'fv8='; bluetoothManager: any; bluetoothDevice: any; writeTransactionId: string; monitorTransactionId: string; constructor(bluetoothDevice, bluetoothManager) { super(); this.bluetoothManager = bluetoothManager; this.bluetoothDevice = bluetoothDevice; BluetoothProbeEmitter.TRANSACTION_COUNT++; this.writeTransactionId = BluetoothProbeEmitter.WRITE_TRANSACTION_ID + BluetoothProbeEmitter.TRANSACTION_COUNT; this.monitorTransactionId = BluetoothProbeEmitter.MONITOR_TRANSACTION_ID + BluetoothProbeEmitter.TRANSACTION_COUNT; } start(command, _mockCode) { if (this.savedError) { this.error(this.savedError); } if (this.bluetoothDevice == null) { this.error(createErrorFromCode(BleErrorCode.DeviceDisconnected)); return; } if (this.bluetoothManager.destroyed) { this.error(createErrorFromCode(SFPToolboxErrorCode.BlueManagerDestroyed)); return; } LocalLogger.log('Write', base64ToHex(command)); this.bluetoothDevice.monitorCharacteristicForService( BluetoothProbeEmitter.SERVICE_UUID, BluetoothProbeEmitter.READ_CHARACTERISTIC_UUID, (error, aCharacteristic) => { if (error) { return this.handleBleError(error); } LocalLogger.log('Read', base64ToHex(aCharacteristic.value)); this.emit(aCharacteristic.value); }, this.monitorTransactionId, ); this.bluetoothDevice .writeCharacteristicWithResponseForService( BluetoothProbeEmitter.SERVICE_UUID, BluetoothProbeEmitter.WRITE_CHARACTERISTIC_UUID, command, this.writeTransactionId, ) .catch(error => { this.handleBleError(error); }); } handleBleError(bleError) { if (bleError.errorCode === BleErrorCode.OperationCancelled) { return; } this.error(createErrorFromBleError(bleError)); } cancelPendingTransactions() { this.bluetoothManager?.cancelTransaction(this.writeTransactionId); this.bluetoothManager?.cancelTransaction(this.monitorTransactionId); } async cancel() { if (this.bluetoothManager.destroyed) { return; } this.cancelPendingTransactions(); const connected = this.bluetoothDevice && (await this.bluetoothDevice.isConnected()); if (connected) { await this.sendStop(); } } async sendStop() { LocalLogger.log('Stop', base64ToHex(BluetoothProbeEmitter.STOP_COMMAND_PAYLOAD)); await this.bluetoothDevice .writeCharacteristicWithResponseForService( BluetoothProbeEmitter.SERVICE_UUID, BluetoothProbeEmitter.WRITE_CHARACTERISTIC_UUID, BluetoothProbeEmitter.STOP_COMMAND_PAYLOAD, ) .catch(error => { console.error({ log: 'No funcionó el stop', errorCode: error.errorCode, message: error.message, }); }); await delay(50); } }