264 lines
7.6 KiB
Dart
264 lines
7.6 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 = "";
|
|
String _secondaryThumbprint = "";
|
|
|
|
late BluetoothConnection? _connection;
|
|
late Stream<Uint8List> _connectionStream;
|
|
late StreamSubscription<Uint8List> _connectionStreamSubscription;
|
|
|
|
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() 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'}.');
|
|
}
|
|
/*setState(() {
|
|
_discoveryResults[_discoveryResults.indexOf(
|
|
result)] =
|
|
BluetoothDiscoveryResult(
|
|
device: BluetoothDevice(
|
|
name: device.name ?? '',
|
|
address: address,
|
|
type: device.type,
|
|
bondState: bonded
|
|
? BluetoothBondState.bonded
|
|
: BluetoothBondState.none,
|
|
),
|
|
rssi: result.rssi);
|
|
});*/
|
|
} 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;
|
|
}
|
|
|
|
_connection = await BluetoothConnection.toAddress(_address);
|
|
debugPrint("Connected to the device");
|
|
|
|
_connectionStream = _connection!.input!;
|
|
_connectionStreamSubscription = _connectionStream.listen(_connectionOnListen);
|
|
_connectionStreamSubscription.onDone(_connectionOnDone);
|
|
}
|
|
|
|
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: $data");
|
|
debugPrint("received decoded: $dataDecoded");
|
|
|
|
_messageBufferChars += dataDecoded;
|
|
|
|
if (data[data.length - 1] == 10) {
|
|
debugPrint("received buffer: $_messageBufferChars");
|
|
int spaceIndex = _messageBufferChars.indexOf(" ");
|
|
String firstParameter = "";
|
|
String secondParameter = "";
|
|
try {
|
|
firstParameter = _messageBufferChars.substring(0, spaceIndex);
|
|
secondParameter = _messageBufferChars.substring(spaceIndex + 1, _messageBufferChars.length - 2);
|
|
} catch (ex) {
|
|
debugPrint(ex.toString());
|
|
}
|
|
debugPrint("we still go on!");
|
|
_messageBufferChars = "";
|
|
debugPrint("first: $firstParameter");
|
|
debugPrint("second: $secondParameter");
|
|
if (firstParameter == "fingerprint") {
|
|
debugPrint("received final buffer: $secondParameter");
|
|
_primaryThumbprint = secondParameter;
|
|
debugPrint("{ _secondaryThumbprint: $_secondaryThumbprint }");
|
|
debugPrint("{ id: $id, _primaryThumbprint: $_primaryThumbprint, _secondaryThumbprint: $_secondaryThumbprint }");
|
|
await _registerDevice();
|
|
}
|
|
}
|
|
|
|
/*
|
|
// Allocate buffer for parsed data
|
|
int backspacesCounter = 0;
|
|
for (var byte in data) {
|
|
if (byte == 8 || byte == 127) {
|
|
backspacesCounter++;
|
|
}
|
|
}
|
|
Uint8List buffer = Uint8List(data.length - backspacesCounter);
|
|
int bufferIndex = buffer.length;
|
|
|
|
// Apply backspace control character
|
|
backspacesCounter = 0;
|
|
for (int i = data.length - 1; i >= 0; i--) {
|
|
if (data[i] == 8 || data[i] == 127) {
|
|
backspacesCounter++;
|
|
} else {
|
|
if (backspacesCounter > 0) {
|
|
backspacesCounter--;
|
|
} else {
|
|
buffer[--bufferIndex] = data[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create message if there is new line character
|
|
String dataString = String.fromCharCodes(buffer);
|
|
int index = buffer.indexOf(13);
|
|
if (~index != 0) {
|
|
_messageBuffer = dataString.substring(index);
|
|
} else {
|
|
_messageBuffer = (backspacesCounter > 0
|
|
? _messageBuffer.substring(0, _messageBuffer.length - backspacesCounter)
|
|
: _messageBuffer + dataString);
|
|
}
|
|
*/
|
|
}
|
|
|
|
Future<void> sendData(String output) async {
|
|
if (_connection == null) return;
|
|
bool nameAvailable = await _cloudServiceAPI.checkNameAvailability(output);
|
|
// String output = "0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ";// !§%&()=?#!?";
|
|
// String output = "myDevice123";// !§%&()=?#!?";
|
|
if (!nameAvailable) return;
|
|
id = output;
|
|
_connection!.output.add(Uint8List.fromList(const AsciiEncoder().convert("$output \r\n")));
|
|
await _connection!.output.allSent;
|
|
debugPrint("sent: $output");
|
|
}
|
|
|
|
Future<void> _registerDevice() async {
|
|
bool registered = false;
|
|
registered = await _cloudServiceAPI.createDevice(id, _primaryThumbprint, "");
|
|
|
|
String statusText =
|
|
registered ? "das Gerät wurde erfolgreich registriert" : "das Gerät konnte nicht registriert werden";
|
|
Fluttertoast.showToast(
|
|
msg: statusText,
|
|
toastLength: Toast.LENGTH_SHORT,
|
|
gravity: ToastGravity.BOTTOM,
|
|
timeInSecForIosWeb: 2,
|
|
backgroundColor: Colors.grey[200],
|
|
textColor: Colors.black,
|
|
fontSize: 16.0);
|
|
}
|
|
}
|
|
|
|
/*setState(() {
|
|
_discoveryResults[_discoveryResults.indexOf(
|
|
result)] =
|
|
BluetoothDiscoveryResult(
|
|
device: BluetoothDevice(
|
|
name: device.name ?? '',
|
|
address: address,
|
|
type: device.type,
|
|
isConnected: connected,
|
|
),
|
|
rssi: result.rssi);
|
|
});
|
|
*/
|