|
1 |
| -import 'dart:async'; |
2 |
| -import 'package:badgemagic/bademagic_module/models/data.dart'; |
3 |
| -import 'package:badgemagic/bademagic_module/utils/data_to_bytearray_converter.dart'; |
4 |
| -import 'package:flutter_blue_plus/flutter_blue_plus.dart'; |
5 |
| -import 'package:logger/logger.dart'; |
6 |
| - |
7 |
| -class BadgeMagicBluetooth { |
8 |
| - static final Logger logger = Logger(); |
9 |
| - |
10 |
| - static Future<void> writeCharacteristic( |
11 |
| - BluetoothDevice device, |
12 |
| - Guid characteristicId, |
13 |
| - Data data, |
14 |
| - ) async { |
15 |
| - List<List<int>> dataChunks = convert(data); |
16 |
| - logger.d("Data to write: $dataChunks"); |
17 |
| - |
18 |
| - try { |
19 |
| - List<BluetoothService> services = await device.discoverServices(); |
20 |
| - for (BluetoothService service in services) { |
21 |
| - for (BluetoothCharacteristic characteristic |
22 |
| - in service.characteristics) { |
23 |
| - if (characteristic.uuid == characteristicId && |
24 |
| - characteristic.properties.write) { |
25 |
| - for (int attempt = 1; attempt <= 3; attempt++) { |
26 |
| - for (List<int> chunk in dataChunks) { |
27 |
| - bool success = false; |
28 |
| - try { |
29 |
| - await characteristic.write(chunk, withoutResponse: false); |
30 |
| - await Future.delayed(const Duration( |
31 |
| - milliseconds: 100)); // Add a delay between writes |
32 |
| - success = true; |
33 |
| - } catch (e) { |
34 |
| - logger.e("Write failed, retrying ($attempt/3): $e"); |
35 |
| - } |
36 |
| - if (!success) { |
37 |
| - throw Exception( |
38 |
| - "Failed to write chunk after 3 attempts: $chunk"); |
39 |
| - } |
40 |
| - } |
41 |
| - } |
42 |
| - logger.d("Characteristic written successfully"); |
43 |
| - return; // Exit once the target characteristic is written |
44 |
| - } |
45 |
| - } |
46 |
| - } |
47 |
| - logger.d("Target characteristic not found"); |
48 |
| - } catch (e) { |
49 |
| - logger.e("Failed to write characteristic: $e"); |
50 |
| - } |
51 |
| - } |
52 |
| - |
53 |
| - static Future<void> scanAndConnect(Data data) async { |
54 |
| - ScanResult? foundDevice; |
55 |
| - |
56 |
| - StreamSubscription<List<ScanResult>>? subscription; |
57 |
| - |
58 |
| - try { |
59 |
| - subscription = FlutterBluePlus.scanResults.listen( |
60 |
| - (results) async { |
61 |
| - if (results.isNotEmpty) { |
62 |
| - foundDevice = results.firstWhere( |
63 |
| - (result) => |
64 |
| - result.device.remoteId.toString() == "50:54:7B:63:10:F5", |
65 |
| - ); |
66 |
| - if (foundDevice != null) { |
67 |
| - await connectToDevice(foundDevice!, data); |
68 |
| - } else { |
69 |
| - logger.e("Target device not found."); |
70 |
| - } |
71 |
| - } |
72 |
| - }, |
73 |
| - onError: (e) { |
74 |
| - logger.e("Scan error: $e"); |
75 |
| - }, |
76 |
| - ); |
77 |
| - |
78 |
| - await FlutterBluePlus.startScan( |
79 |
| - withServices: [Guid("0000fee0-0000-1000-8000-00805f9b34fb")], |
80 |
| - timeout: const Duration(seconds: 10), |
81 |
| - ); |
82 |
| - |
83 |
| - // Wait for the scan to complete before cancelling the subscription |
84 |
| - await Future.delayed(const Duration(seconds: 11)); |
85 |
| - } finally { |
86 |
| - await subscription?.cancel(); |
87 |
| - } |
88 |
| - } |
89 |
| - |
90 |
| - static Future<void> connectToDevice(ScanResult scanResult, Data data) async { |
91 |
| - const int maxRetries = 3; |
92 |
| - int attempt = 0; |
93 |
| - bool connected = false; |
94 |
| - |
95 |
| - while (attempt < maxRetries && !connected) { |
96 |
| - try { |
97 |
| - await scanResult.device.connect(autoConnect: false); |
98 |
| - BluetoothConnectionState connectionState = |
99 |
| - await scanResult.device.connectionState.first; |
100 |
| - |
101 |
| - if (connectionState == BluetoothConnectionState.connected) { |
102 |
| - logger.d("Device connected"); |
103 |
| - await writeCharacteristic( |
104 |
| - scanResult.device, |
105 |
| - Guid("0000fee1-0000-1000-8000-00805f9b34fb"), |
106 |
| - data, |
107 |
| - ); |
108 |
| - connected = true; |
109 |
| - } else { |
110 |
| - logger.e("Failed to connect to the device"); |
111 |
| - } |
112 |
| - } catch (e) { |
113 |
| - logger.e("Connection error: $e"); |
114 |
| - attempt++; |
115 |
| - if (attempt < maxRetries) { |
116 |
| - logger.d("Retrying connection ($attempt/$maxRetries)..."); |
117 |
| - await Future.delayed( |
118 |
| - const Duration(seconds: 2)); // Wait before retrying |
119 |
| - } else { |
120 |
| - logger.e("Max retries reached. Connection failed."); |
121 |
| - } |
122 |
| - } finally { |
123 |
| - if (!connected) { |
124 |
| - await scanResult.device.disconnect(); |
125 |
| - } |
126 |
| - } |
127 |
| - } |
128 |
| - } |
129 |
| -} |
| 1 | +import 'dart:async'; |
| 2 | +import 'package:badgemagic/bademagic_module/models/data.dart'; |
| 3 | +import 'package:badgemagic/bademagic_module/utils/data_to_bytearray_converter.dart'; |
| 4 | +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; |
| 5 | +import 'package:logger/logger.dart'; |
| 6 | + |
| 7 | +class BadgeMagicBluetooth { |
| 8 | + static final Logger logger = Logger(); |
| 9 | + |
| 10 | + static Future<void> writeCharacteristic( |
| 11 | + BluetoothDevice device, |
| 12 | + Guid characteristicId, |
| 13 | + Data data, |
| 14 | + ) async { |
| 15 | + List<List<int>> dataChunks = convert(data); |
| 16 | + logger.d("Data to write: $dataChunks"); |
| 17 | + |
| 18 | + try { |
| 19 | + List<BluetoothService> services = await device.discoverServices(); |
| 20 | + for (BluetoothService service in services) { |
| 21 | + for (BluetoothCharacteristic characteristic |
| 22 | + in service.characteristics) { |
| 23 | + if (characteristic.uuid == characteristicId && |
| 24 | + characteristic.properties.write) { |
| 25 | + for (int attempt = 1; attempt <= 3; attempt++) { |
| 26 | + for (List<int> chunk in dataChunks) { |
| 27 | + bool success = false; |
| 28 | + try { |
| 29 | + await characteristic.write(chunk, withoutResponse: false); |
| 30 | + await Future.delayed(const Duration( |
| 31 | + milliseconds: 100)); // Add a delay between writes |
| 32 | + success = true; |
| 33 | + } catch (e) { |
| 34 | + logger.e("Write failed, retrying ($attempt/3): $e"); |
| 35 | + } |
| 36 | + if (!success) { |
| 37 | + throw Exception( |
| 38 | + "Failed to write chunk after 3 attempts: $chunk"); |
| 39 | + } |
| 40 | + } |
| 41 | + } |
| 42 | + logger.d("Characteristic written successfully"); |
| 43 | + return; // Exit once the target characteristic is written |
| 44 | + } |
| 45 | + } |
| 46 | + } |
| 47 | + logger.d("Target characteristic not found"); |
| 48 | + } catch (e) { |
| 49 | + logger.e("Failed to write characteristic: $e"); |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + static Future<void> scanAndConnect(Data data) async { |
| 54 | + ScanResult? foundDevice; |
| 55 | + |
| 56 | + StreamSubscription<List<ScanResult>>? subscription; |
| 57 | + |
| 58 | + try { |
| 59 | + subscription = FlutterBluePlus.scanResults.listen( |
| 60 | + (results) async { |
| 61 | + if (results.isNotEmpty) { |
| 62 | + foundDevice = results.firstWhere( |
| 63 | + (result) => |
| 64 | + result.device.remoteId.toString() == "50:54:7B:63:10:F5", |
| 65 | + ); |
| 66 | + if (foundDevice != null) { |
| 67 | + await connectToDevice(foundDevice!, data); |
| 68 | + } else { |
| 69 | + logger.e("Target device not found."); |
| 70 | + } |
| 71 | + } |
| 72 | + }, |
| 73 | + onError: (e) { |
| 74 | + logger.e("Scan error: $e"); |
| 75 | + }, |
| 76 | + ); |
| 77 | + |
| 78 | + await FlutterBluePlus.startScan( |
| 79 | + withServices: [Guid("0000fee0-0000-1000-8000-00805f9b34fb")], |
| 80 | + timeout: const Duration(seconds: 10), |
| 81 | + ); |
| 82 | + |
| 83 | + // Wait for the scan to complete before cancelling the subscription |
| 84 | + await Future.delayed(const Duration(seconds: 11)); |
| 85 | + } finally { |
| 86 | + await subscription?.cancel(); |
| 87 | + } |
| 88 | + } |
| 89 | + |
| 90 | + static Future<void> connectToDevice(ScanResult scanResult, Data data) async { |
| 91 | + const int maxRetries = 3; |
| 92 | + int attempt = 0; |
| 93 | + bool connected = false; |
| 94 | + |
| 95 | + while (attempt < maxRetries && !connected) { |
| 96 | + try { |
| 97 | + await scanResult.device.connect(autoConnect: false); |
| 98 | + BluetoothConnectionState connectionState = |
| 99 | + await scanResult.device.connectionState.first; |
| 100 | + |
| 101 | + if (connectionState == BluetoothConnectionState.connected) { |
| 102 | + logger.d("Device connected"); |
| 103 | + await writeCharacteristic( |
| 104 | + scanResult.device, |
| 105 | + Guid("0000fee1-0000-1000-8000-00805f9b34fb"), |
| 106 | + data, |
| 107 | + ); |
| 108 | + connected = true; |
| 109 | + } else { |
| 110 | + logger.e("Failed to connect to the device"); |
| 111 | + } |
| 112 | + } catch (e) { |
| 113 | + logger.e("Connection error: $e"); |
| 114 | + attempt++; |
| 115 | + if (attempt < maxRetries) { |
| 116 | + logger.d("Retrying connection ($attempt/$maxRetries)..."); |
| 117 | + await Future.delayed( |
| 118 | + const Duration(seconds: 2)); // Wait before retrying |
| 119 | + } else { |
| 120 | + logger.e("Max retries reached. Connection failed."); |
| 121 | + } |
| 122 | + } finally { |
| 123 | + if (!connected) { |
| 124 | + await scanResult.device.disconnect(); |
| 125 | + } |
| 126 | + } |
| 127 | + } |
| 128 | + } |
| 129 | +} |
0 commit comments