Files
Bus-Infotainment--IBus-/lib/backend/modules/directconnection.dart
2024-05-24 20:17:02 +01:00

123 lines
3.7 KiB
Dart

import 'dart:async';
import 'package:bus_infotainment/backend/live_information.dart';
import 'package:flutter/foundation.dart';
import 'package:nearby_service/nearby_service.dart';
import 'package:nearby_service/src/model/model.dart';
class NearbyServiceWrapper {
late NearbyService _nearbyService;
final ValueNotifier<bool> isConnected = ValueNotifier(false);
final ValueNotifier<NearbyDevice?> connectedDevice = ValueNotifier(null);
NearbyServiceWrapper() {
_nearbyService = NearbyService.getInstance();
_initializeService();
}
Future<void> _initializeService() async {
await _nearbyService.initialize();
_listenForIncomingConnections();
await startDiscovery();
}
Future<void> startDiscovery() async {
await _nearbyService.discover();
}
Future<void> stopDiscovery() async {
await _nearbyService.stopDiscovery();
}
Future<List<NearbyDevice>> getDiscoveredDevices() async {
List<NearbyDevice> devices = await _nearbyService.getPeers();
// Remove devices that we should avoid
devices.removeWhere((element) => _deviceNamesToAvoid.any((avoid) => element.info.displayName.contains(avoid)));
return devices;
}
Future<void> connectToDevice(NearbyDevice device) async {
bool success = await _nearbyService.connect(device);
if (success) {
connectedDevice.value = device;
isConnected.value = true;
_startCommunicationChannel();
}
}
Future<void> _startCommunicationChannel() async {
await _nearbyService.startCommunicationChannel(
NearbyCommunicationChannelData(
connectedDevice.value!.info.id,
messagesListener: NearbyServiceMessagesListener(
onCreated: () {
print('Communication channel created');
},
onData: (ReceivedNearbyMessage<NearbyMessageContent> value) {
if (value.content is NearbyMessageTextRequest) {
String message = (value.content as NearbyMessageTextRequest).value;
print('Received message: ${message}');
LiveInformation().executeCommand(message);
}
}
)
)
);
}
Future<void> sendMessage(String message) async {
if (isConnected.value && connectedDevice.value != null) {
await _nearbyService.send(
OutgoingNearbyMessage(
content: NearbyMessageTextRequest.create(value: message),
receiver: connectedDevice.value!.info,
)
);
}
}
Future<void> disconnect() async {
if (isConnected.value && connectedDevice.value != null) {
await _nearbyService.disconnect(connectedDevice.value);
connectedDevice.value = null;
isConnected.value = false;
}
}
void _listenForIncomingConnections() {
_nearbyService.getPeersStream().listen((peers) async {
for (var peer in peers) {
// Lets avoid accidentally connecting to things
if (_deviceNamesToAvoid.any((element) => peer.info.displayName.contains(element))) {
print('Avoiding device: ${peer.info.displayName}');
continue;
}
if (!isConnected.value) {
await connectToDevice(peer);
print('Reconnected to: ${peer.info.displayName}');
}
}
});
_nearbyService.getConnectedDeviceStream(connectedDevice.value!).listen((device) {
if (device == null) {
isConnected.value = false;
connectedDevice.value = null;
}
});
}
ValueListenable<NearbyDevice?> get connectedDeviceNotifier => connectedDevice;
ValueListenable<bool> get isConnectedNotifier => isConnected;
}
// If a device name contains any of these strings, it will be avoided
List<String> _deviceNamesToAvoid = [
"DIRECT-", // Avoid connecting to printers
];