// src/backends/bluez/bluez-runtime-types.ts import type { AdvertisementObservation, OwnerScanOptions } from '../../backend-contract/advertisement' import type { CleanupRecord } from '../../backend-contract/errors' import type { NotificationValue } from '../../backend-contract/gatt' import type { BackendOperationPhysicalSettlement, OperationTerminalRecord } from '../../backend-contract/operations' import type { BackendOperationHandle, ClientId, LeaseId, PeerId, ScanSessionId, ScanShareToken, SubscriptionId, Uuid } from '../../backend-contract/primitives' import { capacity } from '../../backend-contract/primitives' import { CoreBoundedStream } from '../../core/bounded-stream' import type { BluezConnection, BluezConnectionLease, BluezGattDatabase } from './bluez-backend-handles' import type { BluezVariant } from './bluez-dbus-contract' export const bluezEventLimits = Object.freeze({ itemCapacity: capacity(64), byteCapacity: capacity(64 * 1024), reservedControlCapacity: capacity(1) }) export const bluezStateLimits = Object.freeze({ itemCapacity: capacity(16), byteCapacity: capacity(16 * 1024), reservedControlCapacity: capacity(1) }) export interface BluezScanConsumer { readonly scanSessionId: ScanSessionId readonly leaseId: LeaseId readonly shareToken: ScanShareToken | null readonly clientId: ClientId readonly options: OwnerScanOptions readonly stream: CoreBoundedStream> readonly abort: (() => void) | null deadlineTimer: ReturnType | null stopped: Promise | null } export interface BluezScanGroup { readonly ownerLeaseId: LeaseId readonly shareToken: ScanShareToken | null readonly signature: string readonly consumers: Map state: 'starting' | 'active' | 'stopping' physicalStarted: boolean filterApplied: boolean filterSettled: boolean discoverySettled: boolean setFilter: Promise | null startDiscovery: Promise | null stopDiscoveryRequested: boolean stopDiscovery: Promise | null filterClearRequested: boolean filterClear: Promise | null /** Owner filter that still needs SetDiscoveryFilter after a failed address-widen restore. */ pendingFilterRestore: BluezVariant | null /** Address-connect waiters currently relying on a temporarily widened scan filter. */ addressWidenBorrowers: number /** Shared widen SetDiscoveryFilter; null when the owner filter is in force. */ addressWiden: Promise | null /** In-flight owner-filter restore after the last address-widen borrower leaves. */ addressWidenRestore: Promise | null stopRequested: boolean resetRequested: boolean startupComplete: boolean readonly startupSettled: Promise readonly settleStartup: () => void } export interface BluezAddressAcquisition { readonly completion: Promise waiters: number connectDevice: Promise | null /** Owned compensating Disconnect after a late ConnectDevice; null means retryable. */ compensation: Promise | null } export interface BluezConnectionRecord { readonly devicePath: string readonly peerId: PeerId connection: BluezConnection | null readonly leases: Set readonly databases: Set readonly pendingOperations: Map, BluezPendingConnectionOperation> state: 'connecting' | 'connected' | 'disconnecting' | 'disconnected' | 'lost' active: boolean /** A Connect call or an existing BlueZ link requires destroy-time Disconnect even before confirmation. */ physicalLinkMayExist: boolean ownerLeaseId: LeaseId | null nextDatabaseGeneration: number currentDatabase: BluezGattDatabase | null transition: Promise | null disconnection: Promise | null disconnectRequested: boolean disconnectMethod: Promise | null pendingConnectors: number orphanCleanupScheduled: boolean } export interface BluezPendingConnectionOperation { readonly operationName: string readonly physicalSettlement: BackendOperationPhysicalSettlement } export interface BluezGattDescriptorRecord { readonly objectPath: string readonly uuid: Uuid } export interface BluezGattCharacteristicRecord { readonly objectPath: string readonly uuid: Uuid readonly flags: readonly string[] readonly descriptors: readonly BluezGattDescriptorRecord[] } export interface BluezGattServiceRecord { readonly objectPath: string readonly uuid: Uuid readonly primary: boolean readonly includedServices: readonly { readonly objectPath: string; readonly uuid: Uuid }[] readonly characteristics: readonly BluezGattCharacteristicRecord[] } export interface BluezGattSnapshotRecord { readonly services: readonly BluezGattServiceRecord[] } export interface BluezPhysicalSubscription { readonly objectPath: string readonly consumers: Set readonly pendingRemovals: Set pendingConsumers: number state: 'enabling' | 'enabling-failed' | 'ready' | 'removing' readonly startMethod: Promise readonly enablement: Promise removal: Promise | null stopMethod: Promise | null stopRequested: boolean } export interface BluezSubscriptionRecord { readonly subscriptionId: SubscriptionId readonly ownerLeaseId: LeaseId readonly stream: CoreBoundedStream readonly terminal: OperationTerminalRecord readonly physical: BluezPhysicalSubscription removed: boolean } export interface BluezPropertyWaiter { /** 'interface-presence' waiters resolve as soon as the interface exists at the path. */ readonly kind?: 'property' | 'interface-presence' readonly path: string readonly interfaceName: string readonly property: string readonly expected: boolean readonly resolve: () => void readonly reject: (error: Error) => void readonly signal: AbortSignal | null readonly abort: () => void timer: ReturnType | null }