mirror of
https://github.com/localsend/localsend.git
synced 2026-08-07 07:14:52 +00:00
271 lines
10 KiB
Dart
271 lines
10 KiB
Dart
// This file is automatically generated, so please do not edit it.
|
|
// @generated by `flutter_rust_bridge`@ 2.12.0.
|
|
|
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
|
|
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
|
import 'package:localsend_isolates/rust/api/model.dart';
|
|
import 'package:localsend_isolates/rust/frb_generated.dart';
|
|
|
|
// These functions are ignored because they are not marked as `pub`: `rs_stored_device`, `stop`
|
|
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `DiscoveryInstance`
|
|
|
|
/// Starts the discovery: binds the UDP multicast sockets on all usable
|
|
/// network interfaces, answers announcements of other devices with an HTTP
|
|
/// register request, and keeps the store of confirmed devices.
|
|
///
|
|
/// Announcements are received from the IPv4 [group] and, as a LocalSend
|
|
/// extension, from the (currently hardcoded) IPv6 group `ff12::fd3a:e420`.
|
|
///
|
|
/// [port] is used both to bind the multicast sockets and as the HTTP server
|
|
/// port announced to other devices. [cert_pem] and [private_key_pem] are this
|
|
/// device's TLS identity, sent as client certificate with every register
|
|
/// request; [fingerprint] must be the certificate's SHA-256 fingerprint.
|
|
///
|
|
/// Nothing is announced until [RsDiscovery::announce] is called.
|
|
///
|
|
/// Cannot fail besides an invalid [group]: when no multicast socket could be
|
|
/// bound (e.g. the port is taken by another process), discovery still runs
|
|
/// without multicast — see [RsDiscovery::multicast_error] — and still learns
|
|
/// about devices through [RsDiscovery::discover], [RsDiscovery::scan_subnet]
|
|
/// and [RsDiscovery::add_device].
|
|
Future<RsDiscovery> startDiscovery({
|
|
required String group,
|
|
required int port,
|
|
List<String>? networkWhitelist,
|
|
List<String>? networkBlacklist,
|
|
required String alias,
|
|
required String version,
|
|
String? deviceModel,
|
|
DeviceType? deviceType,
|
|
required String fingerprint,
|
|
required ProtocolType protocol,
|
|
required bool download,
|
|
required String certPem,
|
|
required String privateKeyPem,
|
|
required BigInt timeoutMs,
|
|
}) => RustLib.instance.api.crateApiDiscoveryStartDiscovery(
|
|
group: group,
|
|
port: port,
|
|
networkWhitelist: networkWhitelist,
|
|
networkBlacklist: networkBlacklist,
|
|
alias: alias,
|
|
version: version,
|
|
deviceModel: deviceModel,
|
|
deviceType: deviceType,
|
|
fingerprint: fingerprint,
|
|
protocol: protocol,
|
|
download: download,
|
|
certPem: certPem,
|
|
privateKeyPem: privateKeyPem,
|
|
timeoutMs: timeoutMs,
|
|
);
|
|
|
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<RsDiscovery>>
|
|
abstract class RsDiscovery implements RustOpaqueInterface {
|
|
/// Puts a device confirmed outside of the discovery into the store, e.g.
|
|
/// one that answered an announcement by registering with this device's
|
|
/// HTTP server. The device is emitted on [RsDiscovery::listen].
|
|
Future<void> addDevice({required RsDiscoveredDevice device});
|
|
|
|
/// Announces this device to the network, which makes every other LocalSend
|
|
/// device on it register with this device over HTTP.
|
|
///
|
|
/// Devices registering in response arrive at the application as server
|
|
/// events, not here: feed them back via [RsDiscovery::add_device].
|
|
///
|
|
/// Returns once the whole announcement burst has been sent, which takes a
|
|
/// few seconds, or immediately once the discovery has been stopped or
|
|
/// multicast is unavailable.
|
|
Future<void> announce();
|
|
|
|
/// Discovers a device at a known address, e.g. a favorite or a peer that
|
|
/// multicast does not reach, by sending it a register request.
|
|
///
|
|
/// The confirmed device is also emitted on [RsDiscovery::listen].
|
|
/// Returns `None` when the device did not answer or answered with this
|
|
/// device's own fingerprint (i.e. the device discovered itself).
|
|
Future<RsStoredDevice?> discover({required String host, required int port, required ProtocolType protocol});
|
|
|
|
/// Emits a [RsStoredDevice] for every device confirmation until the
|
|
/// discovery is stopped. Can only be listened to once.
|
|
///
|
|
/// Also returns when the Dart side of the stream is gone (e.g. after a
|
|
/// hot restart), so this call does not keep the discovery alive forever.
|
|
Stream<RsStoredDevice> listen();
|
|
|
|
/// The reason the multicast sockets could not be bound, when they could
|
|
/// not. Discovery then neither hears nor sends announcements.
|
|
Future<String?> multicastError();
|
|
|
|
/// Scans the `/24` subnet of the local interface address [interface_ip]
|
|
/// by sending every other host a register request, for networks that do
|
|
/// not carry multicast.
|
|
///
|
|
/// The found devices are emitted on [RsDiscovery::listen] as they answer;
|
|
/// this method returns once the whole scan has finished. At most one scan
|
|
/// runs per interface: a call for an address that is still being scanned
|
|
/// returns immediately.
|
|
Future<void> scanSubnet({required String interfaceIp, required int port, required ProtocolType protocol});
|
|
|
|
/// Sets whether announcements of other devices are answered with a
|
|
/// register request (the answer is what makes the announcing device enter
|
|
/// the store). On by default.
|
|
///
|
|
/// Turned off while the HTTP server is not running: the answer would
|
|
/// advertise a port that nobody listens on.
|
|
Future<void> setAnswerAnnouncements({required bool answer});
|
|
|
|
/// Stops the discovery, which also ends the [RsDiscovery::listen] stream.
|
|
/// Returns after all sockets are closed, so the port can be bound again.
|
|
Future<void> stop();
|
|
}
|
|
|
|
/// An address a stored device was confirmed on and is dialed at.
|
|
class RsDeviceChannel {
|
|
/// The host to dial: an IP address, or the scoped form `fe80::1%3` for
|
|
/// link-local IPv6 (the Rust HTTP client accepts both back as a host).
|
|
final String host;
|
|
|
|
/// The port of the device's HTTP server at this address.
|
|
final int port;
|
|
final ProtocolType protocol;
|
|
|
|
const RsDeviceChannel({
|
|
required this.host,
|
|
required this.port,
|
|
required this.protocol,
|
|
});
|
|
|
|
@override
|
|
int get hashCode => host.hashCode ^ port.hashCode ^ protocol.hashCode;
|
|
|
|
@override
|
|
bool operator ==(Object other) =>
|
|
identical(this, other) ||
|
|
other is RsDeviceChannel && runtimeType == other.runtimeType && host == other.host && port == other.port && protocol == other.protocol;
|
|
}
|
|
|
|
/// A single device confirmation over HTTP, fed into the store via
|
|
/// [RsDiscovery::add_device]: the device's register request was accepted by
|
|
/// our server, so it is known to be reachable at [RsDiscoveredDevice::host].
|
|
class RsDiscoveredDevice {
|
|
final String alias;
|
|
|
|
/// Protocol version (major.minor) implemented by the device.
|
|
final String version;
|
|
final String? deviceModel;
|
|
final DeviceType? deviceType;
|
|
|
|
/// Fingerprint identifying the device; devices are deduplicated by it.
|
|
final String fingerprint;
|
|
|
|
/// The host the device was confirmed on: an IP address, or the scoped
|
|
/// form `fe80::1%3` for link-local IPv6 (the Rust HTTP client accepts
|
|
/// both back as a host).
|
|
final String host;
|
|
|
|
/// The port of the device's HTTP server.
|
|
final int port;
|
|
final ProtocolType protocol;
|
|
|
|
/// Whether the device's download API is active.
|
|
final bool download;
|
|
|
|
const RsDiscoveredDevice({
|
|
required this.alias,
|
|
required this.version,
|
|
this.deviceModel,
|
|
this.deviceType,
|
|
required this.fingerprint,
|
|
required this.host,
|
|
required this.port,
|
|
required this.protocol,
|
|
required this.download,
|
|
});
|
|
|
|
@override
|
|
int get hashCode =>
|
|
alias.hashCode ^
|
|
version.hashCode ^
|
|
deviceModel.hashCode ^
|
|
deviceType.hashCode ^
|
|
fingerprint.hashCode ^
|
|
host.hashCode ^
|
|
port.hashCode ^
|
|
protocol.hashCode ^
|
|
download.hashCode;
|
|
|
|
@override
|
|
bool operator ==(Object other) =>
|
|
identical(this, other) ||
|
|
other is RsDiscoveredDevice &&
|
|
runtimeType == other.runtimeType &&
|
|
alias == other.alias &&
|
|
version == other.version &&
|
|
deviceModel == other.deviceModel &&
|
|
deviceType == other.deviceType &&
|
|
fingerprint == other.fingerprint &&
|
|
host == other.host &&
|
|
port == other.port &&
|
|
protocol == other.protocol &&
|
|
download == other.download;
|
|
}
|
|
|
|
/// The merged stored state of a discovered device: one entry per fingerprint,
|
|
/// carrying every address the device was confirmed on. A multi-homed device
|
|
/// that is reachable over several network interfaces is still one
|
|
/// [RsStoredDevice].
|
|
///
|
|
/// Emitted on [RsDiscovery::listen] for every confirmation (answered
|
|
/// announcements, scan results and devices fed in via
|
|
/// [RsDiscovery::add_device]), so a device re-appears — with its channels
|
|
/// accumulated so far — whenever it re-announces itself or is re-discovered.
|
|
class RsStoredDevice {
|
|
final String alias;
|
|
|
|
/// Protocol version (major.minor) implemented by the device.
|
|
final String version;
|
|
final String? deviceModel;
|
|
final DeviceType? deviceType;
|
|
|
|
/// Fingerprint identifying the device; devices are deduplicated by it.
|
|
final String fingerprint;
|
|
|
|
/// Whether the device's download API is active.
|
|
final bool download;
|
|
|
|
/// Every address the device was confirmed on, best first (available
|
|
/// before not-reachable, IPv6 before IPv4, most recently confirmed
|
|
/// first). Never empty: a device only enters the store through a
|
|
/// confirmation.
|
|
final List<RsDeviceChannel> channels;
|
|
|
|
const RsStoredDevice({
|
|
required this.alias,
|
|
required this.version,
|
|
this.deviceModel,
|
|
this.deviceType,
|
|
required this.fingerprint,
|
|
required this.download,
|
|
required this.channels,
|
|
});
|
|
|
|
@override
|
|
int get hashCode =>
|
|
alias.hashCode ^ version.hashCode ^ deviceModel.hashCode ^ deviceType.hashCode ^ fingerprint.hashCode ^ download.hashCode ^ channels.hashCode;
|
|
|
|
@override
|
|
bool operator ==(Object other) =>
|
|
identical(this, other) ||
|
|
other is RsStoredDevice &&
|
|
runtimeType == other.runtimeType &&
|
|
alias == other.alias &&
|
|
version == other.version &&
|
|
deviceModel == other.deviceModel &&
|
|
deviceType == other.deviceType &&
|
|
fingerprint == other.fingerprint &&
|
|
download == other.download &&
|
|
channels == other.channels;
|
|
}
|