package com.megster.cordova.ble.central; import android.app.Activity; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCallback; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.os.Build; import android.os.Handler; import android.util.Base64; import androidx.core.app.NotificationCompat; import com.nordnetab.cordova.ul.parser.XmlTags; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.cordova.CallbackContext; import org.apache.cordova.LOG; import org.apache.cordova.PluginResult; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class Peripheral extends BluetoothGattCallback { public static final UUID CLIENT_CHARACTERISTIC_CONFIGURATION_UUID = UUIDHelper.uuidFromString("2902"); private static final int FAKE_PERIPHERAL_RSSI = Integer.MAX_VALUE; private static final String TAG = "Peripheral"; private byte[] advertisingData; private int advertisingRSSI; private boolean autoconnect = false; private boolean bleProcessing; private ConcurrentLinkedQueue<BLECommand> commandQueue = new ConcurrentLinkedQueue<>(); private CallbackContext connectCallback; private boolean connected = false; private boolean connecting = false; private Activity currentActivity; private BluetoothDevice device; BluetoothGatt gatt; private Map<String, SequentialCallbackContext> notificationCallbacks = new HashMap(); private CallbackContext readCallback; private CallbackContext refreshCallback; private CallbackContext requestMtuCallback; private CallbackContext writeCallback; public Peripheral(BluetoothDevice bluetoothDevice) { LOG.d(TAG, "Creating un-scanned peripheral entry for address: %s", bluetoothDevice.getAddress()); this.device = bluetoothDevice; this.advertisingRSSI = FAKE_PERIPHERAL_RSSI; this.advertisingData = null; } public Peripheral(BluetoothDevice bluetoothDevice, int i, byte[] bArr) { this.device = bluetoothDevice; this.advertisingRSSI = i; this.advertisingData = bArr; } private void gattConnect() { BluetoothGatt bluetoothGatt = this.gatt; if (bluetoothGatt != null) { bluetoothGatt.disconnect(); this.gatt.close(); this.gatt = null; } this.connected = false; this.connecting = true; queueCleanup(); callbackCleanup(); BluetoothDevice device2 = getDevice(); if (Build.VERSION.SDK_INT < 23) { this.gatt = device2.connectGatt(this.currentActivity, this.autoconnect, this); } else { this.gatt = device2.connectGatt(this.currentActivity, this.autoconnect, this, 2); } } public void connect(CallbackContext callbackContext, Activity activity, boolean z) { this.currentActivity = activity; this.autoconnect = z; this.connectCallback = callbackContext; gattConnect(); PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT); pluginResult.setKeepCallback(true); callbackContext.sendPluginResult(pluginResult); } public void disconnect() { this.connected = false; this.connecting = false; BluetoothGatt bluetoothGatt = this.gatt; if (bluetoothGatt != null) { bluetoothGatt.disconnect(); this.gatt.close(); this.gatt = null; } queueCleanup(); callbackCleanup(); } private void peripheralDisconnected() { BluetoothGatt bluetoothGatt; this.connected = false; this.connecting = false; if (!this.autoconnect && (bluetoothGatt = this.gatt) != null) { bluetoothGatt.disconnect(); this.gatt.close(); this.gatt = null; } sendDisconnectMessage(); queueCleanup(); callbackCleanup(); } private void sendDisconnectMessage() { if (this.connectCallback != null) { JSONObject asJSONObject = asJSONObject("Peripheral Disconnected"); if (this.autoconnect) { PluginResult pluginResult = new PluginResult(PluginResult.Status.ERROR, asJSONObject); pluginResult.setKeepCallback(true); this.connectCallback.sendPluginResult(pluginResult); return; } this.connectCallback.error(asJSONObject); this.connectCallback = null; } } public void onMtuChanged(BluetoothGatt bluetoothGatt, int i, int i2) { super.onMtuChanged(bluetoothGatt, i, i2); LOG.d(TAG, "mtu=%d, status=%d", Integer.valueOf(i), Integer.valueOf(i2)); if (i2 == 0) { this.requestMtuCallback.success(i); } else { this.requestMtuCallback.error("MTU request failed"); } this.requestMtuCallback = null; } public void requestMtu(CallbackContext callbackContext, int i) { LOG.d(TAG, "requestMtu mtu=%d", Integer.valueOf(i)); if (this.gatt == null) { callbackContext.error("No GATT"); } else if (Build.VERSION.SDK_INT < 21) { callbackContext.error("Android version does not support requestMtu"); } else if (this.gatt.requestMtu(i)) { this.requestMtuCallback = callbackContext; } else { callbackContext.error("Could not initiate MTU request"); } } public void requestConnectionPriority(int i) { if (this.gatt != null) { LOG.d(TAG, "requestConnectionPriority priority=" + i); if (Build.VERSION.SDK_INT >= 21) { this.gatt.requestConnectionPriority(i); } } } /* JADX WARNING: Removed duplicated region for block: B:16:0x0051 */ /* JADX WARNING: Removed duplicated region for block: B:18:? A[RETURN, SYNTHETIC] */ public void refreshDeviceCache(CallbackContext callbackContext, final long j) { Exception e; LOG.d(TAG, "refreshDeviceCache"); BluetoothGatt bluetoothGatt = this.gatt; boolean z = false; if (bluetoothGatt != null) { try { Method method = bluetoothGatt.getClass().getMethod("refresh", new Class[0]); if (method != null) { boolean booleanValue = ((Boolean) method.invoke(this.gatt, new Object[0])).booleanValue(); if (booleanValue) { try { this.refreshCallback = callbackContext; new Handler().postDelayed(new Runnable() { /* class com.megster.cordova.ble.central.Peripheral.AnonymousClass1 */ public void run() { LOG.d(Peripheral.TAG, "Waiting " + j + " milliseconds before discovering services"); Peripheral.this.gatt.discoverServices(); } }, j); } catch (Exception e2) { e = e2; z = booleanValue; } } z = booleanValue; } else { LOG.w(TAG, "Refresh method not found on gatt"); } } catch (Exception e3) { e = e3; LOG.e(TAG, "refreshDeviceCache Failed", e); if (z) { } } } if (z) { callbackContext.error("Service refresh failed"); } } public boolean isUnscanned() { return this.advertisingData == null; } public JSONObject asJSONObject() { JSONObject jSONObject = new JSONObject(); try { jSONObject.put(XmlTags.HOST_NAME_ATTRIBUTE, this.device.getName()); jSONObject.put("id", this.device.getAddress()); if (this.advertisingData != null) { jSONObject.put("advertising", byteArrayToJSON(this.advertisingData)); } if (this.advertisingRSSI != FAKE_PERIPHERAL_RSSI) { jSONObject.put("rssi", this.advertisingRSSI); } } catch (JSONException e) { e.printStackTrace(); } return jSONObject; } public JSONObject asJSONObject(String str) { JSONObject jSONObject = new JSONObject(); try { jSONObject.put(XmlTags.HOST_NAME_ATTRIBUTE, this.device.getName()); jSONObject.put("id", this.device.getAddress()); jSONObject.put("errorMessage", str); } catch (JSONException e) { e.printStackTrace(); } return jSONObject; } public JSONObject asJSONObject(BluetoothGatt bluetoothGatt) { JSONObject asJSONObject = asJSONObject(); try { JSONArray jSONArray = new JSONArray(); JSONArray jSONArray2 = new JSONArray(); asJSONObject.put("services", jSONArray); asJSONObject.put("characteristics", jSONArray2); if (this.connected && bluetoothGatt != null) { for (BluetoothGattService bluetoothGattService : bluetoothGatt.getServices()) { jSONArray.put(UUIDHelper.uuidToString(bluetoothGattService.getUuid())); for (BluetoothGattCharacteristic bluetoothGattCharacteristic : bluetoothGattService.getCharacteristics()) { JSONObject jSONObject = new JSONObject(); jSONArray2.put(jSONObject); jSONObject.put(NotificationCompat.CATEGORY_SERVICE, UUIDHelper.uuidToString(bluetoothGattService.getUuid())); jSONObject.put("characteristic", UUIDHelper.uuidToString(bluetoothGattCharacteristic.getUuid())); jSONObject.put("properties", Helper.decodeProperties(bluetoothGattCharacteristic)); if (bluetoothGattCharacteristic.getPermissions() > 0) { jSONObject.put("permissions", Helper.decodePermissions(bluetoothGattCharacteristic)); } JSONArray jSONArray3 = new JSONArray(); for (BluetoothGattDescriptor bluetoothGattDescriptor : bluetoothGattCharacteristic.getDescriptors()) { JSONObject jSONObject2 = new JSONObject(); jSONObject2.put("uuid", UUIDHelper.uuidToString(bluetoothGattDescriptor.getUuid())); jSONObject2.put("value", bluetoothGattDescriptor.getValue()); if (bluetoothGattDescriptor.getPermissions() > 0) { jSONObject2.put("permissions", Helper.decodePermissions(bluetoothGattDescriptor)); } jSONArray3.put(jSONObject2); } if (jSONArray3.length() > 0) { jSONObject.put("descriptors", jSONArray3); } } } } } catch (JSONException e) { e.printStackTrace(); } return asJSONObject; } static JSONObject byteArrayToJSON(byte[] bArr) throws JSONException { JSONObject jSONObject = new JSONObject(); jSONObject.put("CDVType", "ArrayBuffer"); jSONObject.put("data", Base64.encodeToString(bArr, 2)); return jSONObject; } public boolean isConnected() { return this.connected; } public boolean isConnecting() { return this.connecting; } public BluetoothDevice getDevice() { return this.device; } public void onServicesDiscovered(BluetoothGatt bluetoothGatt, int i) { super.onServicesDiscovered(bluetoothGatt, i); if (i == 0) { PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, asJSONObject(bluetoothGatt)); pluginResult.setKeepCallback(true); CallbackContext callbackContext = this.refreshCallback; if (callbackContext != null) { callbackContext.sendPluginResult(pluginResult); this.refreshCallback = null; return; } this.connectCallback.sendPluginResult(pluginResult); return; } LOG.e(TAG, "Service discovery failed. status = %d", Integer.valueOf(i)); CallbackContext callbackContext2 = this.refreshCallback; if (callbackContext2 != null) { callbackContext2.error(asJSONObject("Service discovery failed")); this.refreshCallback = null; return; } this.connectCallback.error(asJSONObject("Service discovery failed")); disconnect(); } public void onConnectionStateChange(BluetoothGatt bluetoothGatt, int i, int i2) { this.gatt = bluetoothGatt; if (i2 == 2) { LOG.d(TAG, "onConnectionStateChange CONNECTED"); this.connected = true; this.connecting = false; bluetoothGatt.discoverServices(); return; } LOG.d(TAG, "onConnectionStateChange DISCONNECTED"); this.connected = false; peripheralDisconnected(); } public void onCharacteristicChanged(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic) { super.onCharacteristicChanged(bluetoothGatt, bluetoothGattCharacteristic); LOG.d(TAG, "onCharacteristicChanged %s", bluetoothGattCharacteristic); SequentialCallbackContext sequentialCallbackContext = this.notificationCallbacks.get(generateHashKey(bluetoothGattCharacteristic)); if (sequentialCallbackContext != null) { sequentialCallbackContext.sendSequentialResult(bluetoothGattCharacteristic.getValue()); } } public void onCharacteristicRead(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic, int i) { super.onCharacteristicRead(bluetoothGatt, bluetoothGattCharacteristic, i); LOG.d(TAG, "onCharacteristicRead %s", bluetoothGattCharacteristic); synchronized (this) { if (this.readCallback != null) { if (i == 0) { this.readCallback.success(bluetoothGattCharacteristic.getValue()); } else { CallbackContext callbackContext = this.readCallback; callbackContext.error("Error reading " + bluetoothGattCharacteristic.getUuid() + " status=" + i); } this.readCallback = null; } } commandCompleted(); } public void onCharacteristicWrite(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic, int i) { super.onCharacteristicWrite(bluetoothGatt, bluetoothGattCharacteristic, i); LOG.d(TAG, "onCharacteristicWrite %s", bluetoothGattCharacteristic); synchronized (this) { if (this.writeCallback != null) { if (i == 0) { this.writeCallback.success(); } else { this.writeCallback.error(i); } this.writeCallback = null; } } commandCompleted(); } public void onDescriptorWrite(BluetoothGatt bluetoothGatt, BluetoothGattDescriptor bluetoothGattDescriptor, int i) { super.onDescriptorWrite(bluetoothGatt, bluetoothGattDescriptor, i); LOG.d(TAG, "onDescriptorWrite %s", bluetoothGattDescriptor); commandCompleted(); } public void onReadRemoteRssi(BluetoothGatt bluetoothGatt, int i, int i2) { super.onReadRemoteRssi(bluetoothGatt, i, i2); synchronized (this) { if (this.readCallback != null) { if (i2 == 0) { updateRssi(i); this.readCallback.success(i); } else { CallbackContext callbackContext = this.readCallback; callbackContext.error("Error reading RSSI status=" + i2); } this.readCallback = null; } } commandCompleted(); } public void update(int i, byte[] bArr) { this.advertisingRSSI = i; this.advertisingData = bArr; } public void updateRssi(int i) { this.advertisingRSSI = i; } private void registerNotifyCallback(CallbackContext callbackContext, UUID uuid, UUID uuid2) { BluetoothGatt bluetoothGatt = this.gatt; if (bluetoothGatt == null) { callbackContext.error("BluetoothGatt is null"); return; } BluetoothGattCharacteristic findNotifyCharacteristic = findNotifyCharacteristic(bluetoothGatt.getService(uuid), uuid2); String generateHashKey = generateHashKey(uuid, findNotifyCharacteristic); boolean z = false; if (findNotifyCharacteristic != null) { this.notificationCallbacks.put(generateHashKey, new SequentialCallbackContext(callbackContext)); if (this.gatt.setCharacteristicNotification(findNotifyCharacteristic, true)) { BluetoothGattDescriptor descriptor = findNotifyCharacteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIGURATION_UUID); if (descriptor != null) { if ((findNotifyCharacteristic.getProperties() & 16) != 0) { descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); } else if ((findNotifyCharacteristic.getProperties() & 32) != 0) { descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); } else { LOG.w(TAG, "Characteristic %s does not have NOTIFY or INDICATE property set", uuid2); } if (this.gatt.writeDescriptor(descriptor)) { z = true; } else { callbackContext.error("Failed to set client characteristic notification for " + uuid2); } } else { callbackContext.error("Set notification failed for " + uuid2); } } else { callbackContext.error("Failed to register notification for " + uuid2); } } else { callbackContext.error("Characteristic " + uuid2 + " not found"); } if (!z) { commandCompleted(); } } private void removeNotifyCallback(CallbackContext callbackContext, UUID uuid, UUID uuid2) { BluetoothGatt bluetoothGatt = this.gatt; if (bluetoothGatt == null) { callbackContext.error("BluetoothGatt is null"); return; } BluetoothGattCharacteristic findNotifyCharacteristic = findNotifyCharacteristic(bluetoothGatt.getService(uuid), uuid2); String generateHashKey = generateHashKey(uuid, findNotifyCharacteristic); if (findNotifyCharacteristic != null) { this.notificationCallbacks.remove(generateHashKey); if (this.gatt.setCharacteristicNotification(findNotifyCharacteristic, false)) { BluetoothGattDescriptor descriptor = findNotifyCharacteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIGURATION_UUID); if (descriptor != null) { descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); this.gatt.writeDescriptor(descriptor); } callbackContext.success(); } else { callbackContext.error("Failed to stop notification for " + uuid2); } } else { callbackContext.error("Characteristic " + uuid2 + " not found"); } commandCompleted(); } private BluetoothGattCharacteristic findNotifyCharacteristic(BluetoothGattService bluetoothGattService, UUID uuid) { BluetoothGattCharacteristic bluetoothGattCharacteristic; BluetoothGattCharacteristic bluetoothGattCharacteristic2; List<BluetoothGattCharacteristic> characteristics = bluetoothGattService.getCharacteristics(); Iterator<BluetoothGattCharacteristic> it = characteristics.iterator(); while (true) { if (!it.hasNext()) { bluetoothGattCharacteristic = null; break; } bluetoothGattCharacteristic = it.next(); if ((bluetoothGattCharacteristic.getProperties() & 16) != 0 && uuid.equals(bluetoothGattCharacteristic.getUuid())) { break; } } if (bluetoothGattCharacteristic != null) { return bluetoothGattCharacteristic; } Iterator<BluetoothGattCharacteristic> it2 = characteristics.iterator(); while (true) { if (!it2.hasNext()) { bluetoothGattCharacteristic2 = bluetoothGattCharacteristic; break; } bluetoothGattCharacteristic2 = it2.next(); if ((bluetoothGattCharacteristic2.getProperties() & 32) != 0 && uuid.equals(bluetoothGattCharacteristic2.getUuid())) { break; } } return bluetoothGattCharacteristic2 == null ? bluetoothGattService.getCharacteristic(uuid) : bluetoothGattCharacteristic2; } private void readCharacteristic(CallbackContext callbackContext, UUID uuid, UUID uuid2) { BluetoothGatt bluetoothGatt = this.gatt; if (bluetoothGatt == null) { callbackContext.error("BluetoothGatt is null"); return; } BluetoothGattService service = bluetoothGatt.getService(uuid); if (service == null) { callbackContext.error("Service " + uuid + " not found."); return; } BluetoothGattCharacteristic findReadableCharacteristic = findReadableCharacteristic(service, uuid2); boolean z = false; if (findReadableCharacteristic == null) { callbackContext.error("Characteristic " + uuid2 + " not found."); } else { synchronized (this) { this.readCallback = callbackContext; if (this.gatt.readCharacteristic(findReadableCharacteristic)) { z = true; } else { this.readCallback = null; callbackContext.error("Read failed"); } } } if (!z) { commandCompleted(); } } private void readRSSI(CallbackContext callbackContext) { boolean z; if (this.gatt == null) { callbackContext.error("BluetoothGatt is null"); return; } synchronized (this) { this.readCallback = callbackContext; if (this.gatt.readRemoteRssi()) { z = true; } else { this.readCallback = null; callbackContext.error("Read RSSI failed"); z = false; } } if (!z) { commandCompleted(); } } private BluetoothGattCharacteristic findReadableCharacteristic(BluetoothGattService bluetoothGattService, UUID uuid) { BluetoothGattCharacteristic bluetoothGattCharacteristic; Iterator<BluetoothGattCharacteristic> it = bluetoothGattService.getCharacteristics().iterator(); while (true) { if (!it.hasNext()) { bluetoothGattCharacteristic = null; break; } bluetoothGattCharacteristic = it.next(); if ((bluetoothGattCharacteristic.getProperties() & 2) != 0 && uuid.equals(bluetoothGattCharacteristic.getUuid())) { break; } } return bluetoothGattCharacteristic == null ? bluetoothGattService.getCharacteristic(uuid) : bluetoothGattCharacteristic; } private void writeCharacteristic(CallbackContext callbackContext, UUID uuid, UUID uuid2, byte[] bArr, int i) { BluetoothGatt bluetoothGatt = this.gatt; if (bluetoothGatt == null) { callbackContext.error("BluetoothGatt is null"); return; } BluetoothGattService service = bluetoothGatt.getService(uuid); if (service == null) { callbackContext.error("Service " + uuid + " not found."); return; } BluetoothGattCharacteristic findWritableCharacteristic = findWritableCharacteristic(service, uuid2, i); boolean z = false; if (findWritableCharacteristic == null) { callbackContext.error("Characteristic " + uuid2 + " not found."); } else { findWritableCharacteristic.setValue(bArr); findWritableCharacteristic.setWriteType(i); synchronized (this) { this.writeCallback = callbackContext; if (this.gatt.writeCharacteristic(findWritableCharacteristic)) { z = true; } else { this.writeCallback = null; callbackContext.error("Write failed"); } } } if (!z) { commandCompleted(); } } private BluetoothGattCharacteristic findWritableCharacteristic(BluetoothGattService bluetoothGattService, UUID uuid, int i) { BluetoothGattCharacteristic bluetoothGattCharacteristic; int i2 = i == 1 ? 4 : 8; Iterator<BluetoothGattCharacteristic> it = bluetoothGattService.getCharacteristics().iterator(); while (true) { if (!it.hasNext()) { bluetoothGattCharacteristic = null; break; } bluetoothGattCharacteristic = it.next(); if ((bluetoothGattCharacteristic.getProperties() & i2) != 0 && uuid.equals(bluetoothGattCharacteristic.getUuid())) { break; } } return bluetoothGattCharacteristic == null ? bluetoothGattService.getCharacteristic(uuid) : bluetoothGattCharacteristic; } public void queueRead(CallbackContext callbackContext, UUID uuid, UUID uuid2) { queueCommand(new BLECommand(callbackContext, uuid, uuid2, BLECommand.READ)); } public void queueWrite(CallbackContext callbackContext, UUID uuid, UUID uuid2, byte[] bArr, int i) { queueCommand(new BLECommand(callbackContext, uuid, uuid2, bArr, i)); } public void queueRegisterNotifyCallback(CallbackContext callbackContext, UUID uuid, UUID uuid2) { queueCommand(new BLECommand(callbackContext, uuid, uuid2, BLECommand.REGISTER_NOTIFY)); } public void queueRemoveNotifyCallback(CallbackContext callbackContext, UUID uuid, UUID uuid2) { queueCommand(new BLECommand(callbackContext, uuid, uuid2, BLECommand.REMOVE_NOTIFY)); } public void queueReadRSSI(CallbackContext callbackContext) { queueCommand(new BLECommand(callbackContext, null, null, BLECommand.READ_RSSI)); } public void queueCleanup() { this.bleProcessing = false; while (true) { BLECommand poll = this.commandQueue.poll(); if (poll != null) { poll.getCallbackContext().error("Peripheral Disconnected"); } else { return; } } } private void callbackCleanup() { synchronized (this) { if (this.readCallback != null) { this.readCallback.error(asJSONObject("Peripheral Disconnected")); this.readCallback = null; commandCompleted(); } if (this.writeCallback != null) { this.writeCallback.error(asJSONObject("Peripheral Disconnected")); this.writeCallback = null; commandCompleted(); } } } private void queueCommand(BLECommand bLECommand) { LOG.d(TAG, "Queuing Command %s", bLECommand); this.commandQueue.add(bLECommand); PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT); pluginResult.setKeepCallback(true); bLECommand.getCallbackContext().sendPluginResult(pluginResult); if (!this.bleProcessing) { processCommands(); } } private void commandCompleted() { LOG.d(TAG, "Processing Complete"); this.bleProcessing = false; processCommands(); } private void processCommands() { LOG.d(TAG, "Processing Commands"); if (!this.bleProcessing) { BLECommand poll = this.commandQueue.poll(); if (poll == null) { LOG.d(TAG, "Command Queue is empty."); } else if (poll.getType() == BLECommand.READ) { LOG.d(TAG, "Read %s", poll.getCharacteristicUUID()); this.bleProcessing = true; readCharacteristic(poll.getCallbackContext(), poll.getServiceUUID(), poll.getCharacteristicUUID()); } else if (poll.getType() == 2) { LOG.d(TAG, "Write %s", poll.getCharacteristicUUID()); this.bleProcessing = true; writeCharacteristic(poll.getCallbackContext(), poll.getServiceUUID(), poll.getCharacteristicUUID(), poll.getData(), poll.getType()); } else if (poll.getType() == 1) { LOG.d(TAG, "Write No Response %s", poll.getCharacteristicUUID()); this.bleProcessing = true; writeCharacteristic(poll.getCallbackContext(), poll.getServiceUUID(), poll.getCharacteristicUUID(), poll.getData(), poll.getType()); } else if (poll.getType() == BLECommand.REGISTER_NOTIFY) { LOG.d(TAG, "Register Notify %s", poll.getCharacteristicUUID()); this.bleProcessing = true; registerNotifyCallback(poll.getCallbackContext(), poll.getServiceUUID(), poll.getCharacteristicUUID()); } else if (poll.getType() == BLECommand.REMOVE_NOTIFY) { LOG.d(TAG, "Remove Notify %s", poll.getCharacteristicUUID()); this.bleProcessing = true; removeNotifyCallback(poll.getCallbackContext(), poll.getServiceUUID(), poll.getCharacteristicUUID()); } else if (poll.getType() == BLECommand.READ_RSSI) { LOG.d(TAG, "Read RSSI"); this.bleProcessing = true; readRSSI(poll.getCallbackContext()); } else { throw new RuntimeException("Unexpected BLE Command type " + poll.getType()); } } } private String generateHashKey(BluetoothGattCharacteristic bluetoothGattCharacteristic) { return generateHashKey(bluetoothGattCharacteristic.getService().getUuid(), bluetoothGattCharacteristic); } private String generateHashKey(UUID uuid, BluetoothGattCharacteristic bluetoothGattCharacteristic) { return uuid + "|" + bluetoothGattCharacteristic.getUuid() + "|" + bluetoothGattCharacteristic.getInstanceId(); } }