- Phase 1 core protocol: temp_table, neg8, sensor_state, s300_parser, kpro_parser, dtc_map, sensor_defs (50/50 tests passing) - BT layer: bt_service.dart, bt_poller.dart (100ms poll, NEG8 validation) - Connection test UI: device picker, protocol selector, live sensor screen with LIVE DATA + DEBUG LOG tabs - Runtime BT permission request (Android 12+) + auto-enable Bluetooth - Android: minSdk=26, all BT+location permissions in manifest - Fixed flutter_bluetooth_serial namespace for AGP compatibility
57 lines
1.4 KiB
Dart
57 lines
1.4 KiB
Dart
import 'dart:async';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
|
|
|
|
/// Wraps flutter_bluetooth_serial for SPP/RFCOMM Classic BT.
|
|
class BtService {
|
|
BluetoothConnection? _connection;
|
|
final StreamController<Uint8List> _rawFrameController =
|
|
StreamController<Uint8List>.broadcast();
|
|
|
|
bool get isConnected => _connection?.isConnected ?? false;
|
|
|
|
Stream<Uint8List> get rawStream => _rawFrameController.stream;
|
|
|
|
Future<List<BluetoothDevice>> getPairedDevices() async {
|
|
return FlutterBluetoothSerial.instance.getBondedDevices();
|
|
}
|
|
|
|
Future<void> connect(BluetoothDevice device) async {
|
|
if (_connection != null) {
|
|
await disconnect();
|
|
}
|
|
_connection = await BluetoothConnection.toAddress(device.address);
|
|
_connection!.input!.listen(
|
|
(Uint8List data) {
|
|
if (!_rawFrameController.isClosed) {
|
|
_rawFrameController.add(data);
|
|
}
|
|
},
|
|
onDone: () {
|
|
_rawFrameController.addError('BT connection closed');
|
|
},
|
|
onError: (Object e) {
|
|
_rawFrameController.addError(e);
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<void> write(Uint8List data) async {
|
|
if (_connection?.isConnected ?? false) {
|
|
_connection!.output.add(data);
|
|
await _connection!.output.allSent;
|
|
}
|
|
}
|
|
|
|
Future<void> disconnect() async {
|
|
await _connection?.close();
|
|
_connection = null;
|
|
}
|
|
|
|
void dispose() {
|
|
disconnect();
|
|
_rawFrameController.close();
|
|
}
|
|
}
|