writeToBluetoothDevice function

Future<void> writeToBluetoothDevice(
  1. BluetoothDevice device,
  2. List<int> data
)

Schreibt einen fertigen Byte-Strom an ein konkretes device — die geraeteverifizierte Sendelogik (MTU-Aushandlung, Discover, Chunking, Flow-Control/Pacing) an einer Stelle.

Ausgelagert aus KeckPrinterService._sendToBluetoothPrinter, damit sowohl der statische, globale Pfad (KeckPrinterService.printReceiptBluetooth) als auch die transport-basierte BluetoothTransport dieselbe, in der Praxis bewaehrte Logik nutzen — verhaltensgleich, nur unabhaengig vom globalen KeckPrinterService._devicePrinter.

Wirft, wenn kein schreibbares Charakteristikum gefunden wird.

Implementation

Future<void> writeToBluetoothDevice(BluetoothDevice device, List<int> data) async {
  // Groessere MTU aushandeln, wo unterstuetzt (Android); sonst aktuellen Wert nehmen.
  int mtu;
  try {
    mtu = await device.requestMtu(512);
  } catch (_) {
    mtu = device.mtuNow;
  }
  final int chunkSize = (mtu - 3).clamp(20, 182).toInt();

  final List<BluetoothService> services = await device.discoverServices();

  for (final service in services) {
    for (final characteristic in service.characteristics) {
      final bool canWrite = characteristic.properties.write;
      final bool canWriteNoResp = characteristic.properties.writeWithoutResponse;
      if (!canWrite && !canWriteNoResp) continue;

      // Kernproblem war fehlendes Flow-Control: grosse Raster (QR/Logo) wurden mit
      // withoutResponse ohne Backpressure rausgeblasen -> der Drucker-Puffer laeuft
      // ueber -> Zeichensalat + Abbruch. Loesung: write-with-response (wartet aufs
      // ACK = Backpressure) wo moeglich, sonst withoutResponse mit Pacing.
      final bool withoutResponse = !canWrite;
      try {
        for (int i = 0; i < data.length; i += chunkSize) {
          final int end = (i + chunkSize < data.length) ? i + chunkSize : data.length;
          await characteristic.write(data.sublist(i, end), withoutResponse: withoutResponse);
          if (withoutResponse) {
            await Future.delayed(const Duration(milliseconds: 20));
          }
        }
        return; // erfolgreich gesendet
      } catch (e) {
        if (kDebugMode) {
          print("Fehler beim Senden an ${characteristic.uuid}: $e");
        }
      }
    }
  }

  throw Exception("Kein geeignetes Bluetooth-Charakteristikum zum Schreiben gefunden.");
}