Write long data BLE > 20 bytes. Implementation.

After some time and investigation, I ran into a problem about connection interval of Garmin through the BLE.

The peripheral that I use to send and receive data with Garmin watch is expecting that I would send the commands with a delay no more than 100ms.

I wrote my own function writeLongData to send long data of more than 20 bytes by splitting it to smaller packages up to 20 bytes.

And the problem is that from time to time commands are sent with a delay greater than 100ms.

I think that is because I have to wait until the onCharacteristicWrite callback is returned and only after send the next command. Otherwise there will be an error on requestWrite  "Operation already in Progress". So how to handle this problem?

Here is the code:

function writeLongData(cccd as Characteristic?, data as ByteArray) as Void {

  var chunkSize = 20;
  var index = 0;
  while (index < data.size()) {
    var chunk = data.slice(index, min(index + chunkSize, data.size()));
    _commQueue.add(cccd, chunk);

    index += chunkSize;
  }
}
// _commQueue file
public function add(char as Characteristic?, data as ByteArray) as Void {
  if (data.size() > 0) {
    queue.add([char, data]);
    if (!isRunning) {
      run();
    }
  }
}

public function run() as Void {
  if (queue.size() == 0) {
    isRunning = false;
    return;
  }
  isRunning = true;
  var char = queue[0][0];
  char.requestWrite(queue[0][1], {
     :writeType =>BluetoothLowEnergy.WRITE_TYPE_DEFAULT,
  });

  if (queue.size() > 0) {
    queue = queue.slice(1, queue.size());
  }
}
// And on onCharacteristicWrite in BluetoothLowEnergy.BleDelegate
public function onCharacteristicWrite(characteristic asCharacteristicstatus as Status) as Void {
  _commQueue.run();
}