From ad425af50a979816261f8f2e3f6f397cc21467a6 Mon Sep 17 00:00:00 2001 From: Kaoru Shoji <0x0badc0de@gmail.com> Date: Thu, 11 Apr 2024 11:33:51 +0900 Subject: [PATCH] Check if the bluetooth transfer completed --- .../blemidi/central/BleMidiCallback.java | 9 ++++--- .../blemidi/device/MidiOutputDevice.java | 24 ++++++++++++++----- .../peripheral/BleMidiPeripheralProvider.java | 14 +++++++---- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/central/BleMidiCallback.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/central/BleMidiCallback.java index 3ab1efe..bb24f2e 100644 --- a/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/central/BleMidiCallback.java +++ b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/central/BleMidiCallback.java @@ -9,6 +9,7 @@ import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothStatusCodes; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -806,17 +807,19 @@ public void configureAsCentralDevice() { } @Override - public void transferData(@NonNull byte[] writeBuffer) throws SecurityException { + public boolean transferData(@NonNull byte[] writeBuffer) throws SecurityException { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - bluetoothGatt.writeCharacteristic(midiOutputCharacteristic, writeBuffer, BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + int result = bluetoothGatt.writeCharacteristic(midiOutputCharacteristic, writeBuffer, BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + return result == BluetoothStatusCodes.SUCCESS; } else { midiOutputCharacteristic.setValue(writeBuffer); - bluetoothGatt.writeCharacteristic(midiOutputCharacteristic); + return bluetoothGatt.writeCharacteristic(midiOutputCharacteristic); } } catch (Throwable ignored) { // android.os.DeadObjectException will be thrown // ignore it + return false; } } diff --git a/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/device/MidiOutputDevice.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/device/MidiOutputDevice.java index c8750a1..18d67c6 100644 --- a/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/device/MidiOutputDevice.java +++ b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/device/MidiOutputDevice.java @@ -20,8 +20,9 @@ public abstract class MidiOutputDevice { * Transfer data * * @param writeBuffer byte array to write + * @return true if transfer succeed */ - protected abstract void transferData(@NonNull byte[] writeBuffer); + protected abstract boolean transferData(@NonNull byte[] writeBuffer); /** * Obtains the device name @@ -79,14 +80,16 @@ public void run() { while (transferDataThreadAlive && isRunning) { synchronized (transferDataStream) { if (writtenDataCount > 0) { - transferData(transferDataStream.toByteArray()); - transferDataStream.reset(); - writtenDataCount = 0; + if (transferData(transferDataStream.toByteArray())) { + // reset the stream if transfer succeed + transferDataStream.reset(); + writtenDataCount = 0; + } } } try { - Thread.sleep(10); + Thread.sleep(10); // BluetoothGatt.WRITE_CHARACTERISTIC_TIME_TO_WAIT } catch (InterruptedException ignored) { } } @@ -238,7 +241,16 @@ public final void sendMidiSystemExclusive(@NonNull byte[] systemExclusive) { writeBuffer[0] = (byte) (0x80 | ((timestamp >> 7) & 0x3f)); // immediately transfer data - transferData(writeBuffer); + while (true) { + if (transferData(writeBuffer)) { + break; + } + + try { + Thread.sleep(10); // BluetoothGatt.WRITE_CHARACTERISTIC_TIME_TO_WAIT + } catch (InterruptedException ignored) { + } + } timestamp = System.currentTimeMillis() % MAX_TIMESTAMP; } diff --git a/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/peripheral/BleMidiPeripheralProvider.java b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/peripheral/BleMidiPeripheralProvider.java index fd7033d..a567ffa 100644 --- a/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/peripheral/BleMidiPeripheralProvider.java +++ b/BLE-MIDI-library/src/main/java/jp/kshoji/blemidi/peripheral/BleMidiPeripheralProvider.java @@ -12,6 +12,7 @@ import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.le.AdvertiseCallback; import android.bluetooth.le.AdvertiseData; import android.bluetooth.le.AdvertiseSettings; @@ -707,13 +708,18 @@ public String getModel() { } @Override - public void transferData(@NonNull byte[] writeBuffer) throws SecurityException { - midiOutputCharacteristic.setValue(writeBuffer); - + public boolean transferData(@NonNull byte[] writeBuffer) throws SecurityException { try { - bluetoothGattServer.notifyCharacteristicChanged(bluetoothDevice, midiOutputCharacteristic, false); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + int result = bluetoothGattServer.notifyCharacteristicChanged(bluetoothDevice, midiOutputCharacteristic, false, writeBuffer); + return result == BluetoothStatusCodes.SUCCESS; + } else { + midiOutputCharacteristic.setValue(writeBuffer); + return bluetoothGattServer.notifyCharacteristicChanged(bluetoothDevice, midiOutputCharacteristic, false); + } } catch (Throwable ignored) { // ignore it + return false; } }