semesterprojekt-bluetooth-p.../lib/objects/bluetooth_object.dart

198 lines
5.4 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '../objects/cloud_service_api.dart';
class BluetoothObject {
late int _rssi = -1;
late BluetoothDevice _device;
String _address = "";
String _name = "";
String id = "";
String _primaryThumbprint = "";
final String _secondaryThumbprint = "";
late BluetoothConnection? _connection;
late Stream<Uint8List> _connectionStream;
late StreamSubscription<Uint8List> _connectionStreamSubscription;
late BuildContext _context;
final CloudServiceAPI _cloudServiceAPI = CloudServiceAPI();
//late Uint8List _messageBufferBits;
late String _messageBufferChars = "";
bool _isDisconnecting = false;
String get primaryThumbprint {
return _primaryThumbprint;
}
String get secondaryThumbprint {
return _secondaryThumbprint;
}
int get rssi {
return _rssi;
}
String get name {
return _name;
}
String get address {
return _address;
}
BluetoothDevice get device {
return _device;
}
BluetoothConnection? get connection {
return _connection;
}
bool get isConnected {
return (_connection == null ? false : true);
}
BluetoothObject(BluetoothDiscoveryResult result) {
_rssi = result.rssi;
_device = result.device;
_address = _device.address;
_name = _device.name ?? "device.name.UNKNOWN";
_connection = null;
}
Future<void> bondDevice(BuildContext context) async {
try {
bool bonded = false;
if (_device.isBonded) {
debugPrint('Unbonding from $_address...');
await FlutterBluetoothSerial.instance.removeDeviceBondWithAddress(_address);
debugPrint('Unbonding from $_address has succed');
} else {
debugPrint('Bonding with $_address...');
bonded = (await FlutterBluetoothSerial.instance.bondDeviceAtAddress(_address))!;
debugPrint('Bonding with $_address has ${bonded ? 'succed' : 'failed'}.');
}
} catch (ex) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text(
'Error occured while bonding'),
content: Text(ex.toString()),
actions: <Widget>[
TextButton(
child: const Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
Future<void> disconnectDevice() async {
_isDisconnecting = true;
if (_connection != null) {
await _connection!.finish();
_connection = null;
}
_isDisconnecting = false;
}
Future<void> connectDevice() async {
if (isConnected) {
await _connection!.finish();
_connection = null;
}
try {
_connection = await BluetoothConnection.toAddress(_address);
debugPrint("Connected to the device");
_connectionStream = _connection!.input!;
_connectionStreamSubscription = _connectionStream.listen(_connectionOnListen);
_connectionStreamSubscription.onDone(_connectionOnDone);
} catch (ex) {
debugPrint("$ex");
}
}
void _connectionOnDone() {
if (_isDisconnecting) {
debugPrint("Disconnecting locally!");
} else {
debugPrint("Disconnected remotely!");
}
}
Future<void> _connectionOnListen(Uint8List data) async {
final String dataDecoded = const AsciiDecoder().convert(data);
debugPrint("received decoded: $dataDecoded");
_messageBufferChars += dataDecoded;
if (!(data[data.length - 1] == 10)) {
return;
}
if (!_messageBufferChars.contains(" ")) {
_messageBufferChars = "";
return;
}
List<String> input = _messageBufferChars.split(" ");
if (input[0] == "fingerprint") {
_primaryThumbprint = input[1].trim();
debugPrint("_primaryThumbprint: ${const AsciiEncoder().convert(_primaryThumbprint)}");
debugPrint("id: ${const AsciiEncoder().convert(id)}");
debugPrint("_secondaryThumbprint: $_secondaryThumbprint");
await _registerDevice();
}
_messageBufferChars = "";
}
Future<void> sendData(BuildContext context, String output) async {
if (_connection == null) return;
bool nameAvailable = await _cloudServiceAPI.checkNameAvailability(output);
if (!nameAvailable) return;
id = output;
_connection!.output.add(Uint8List.fromList(const AsciiEncoder().convert("$output \r\n")));
await _connection!.output.allSent;
_context = context;
debugPrint("sent: $output");
}
Future<void> _registerDevice() async {
bool registered = false;
registered = await _cloudServiceAPI.createDevice(id, _primaryThumbprint, "");
_confirmRegistration(registered);
}
void _confirmRegistration(bool registered) {
showDialog<String>(
context: _context,
builder: (BuildContext context) => AlertDialog(
title: const Text('Device Info'),
content: Text(registered ? "das Gerät wurde erfolgreich registriert" : "das Gerät konnte nicht registriert werden"),
backgroundColor: Colors.white,
actions: <Widget>[
TextButton(onPressed: () => Navigator.pop(context, 'Cancel'),
child: const Text('OK'),
),
],
),
);
}
}