MC1Services API Reference

June 19, 2026 · View on GitHub

The MC1Services layer provides actor-isolated business logic, managing services, persistence, and device connections.

Package Information

  • Location: MC1Services/
  • Type: Swift Package (single library target)
  • Dependencies: MeshCore

ConnectionManager (public, @MainActor, @Observable class)

File: MC1Services/Sources/MC1Services/Connection/ConnectionManager.swift (split across Connection/ConnectionManager+Lifecycle.swift, +BLE.swift, +Pairing.swift, +WiFi.swift, and Sync/ConnectionManager+SyncRetry.swift)

The primary entry point for managing the connection to a MeshCore device and coordinating services.

Properties

PropertyTypeDescription
connectionStateDeviceConnectionStateCurrent state: .disconnected, .connecting, .connected, .syncing, .ready
connectedDeviceDeviceDTO?Currently connected device info
servicesServiceContainer?Business logic services (available when .ready)
currentTransportTypeTransportType?Active transport type (.bluetooth or .wifi)

Methods

MethodDescription
activate() asyncInitializes and attempts auto-reconnect to last device
pairNewDevice() async throwsStarts AccessorySetupKit pairing flow
connect(to:forceFullSync:forceReconnect:) async throwsConnects to a previously paired device
disconnect(reason:) asyncGracefully disconnects and stops services
forgetDevice(deleteData:) async throwsRemoves device from app and system pairings
forgetDevice(id:) asyncRemoves a device by ID (non-throwing)
switchDevice(to:) async throwsSwitches to a different device
connectViaWiFi(host:port:forceFullSync:) async throwsConnects to a device over WiFi/TCP
clearStalePairings() asyncClears all stale pairings from AccessorySetupKit
fetchSavedDevices() async throws -> [DeviceDTO]Fetches all previously paired devices from storage
hasAccessory(for:) -> BoolChecks if an accessory is registered with AccessorySetupKit
renameCurrentDevice() async throwsRenames the currently connected device via AccessorySetupKit

Additional Properties

PropertyTypeDescription
pairedAccessoriesCountIntNumber of paired accessories (for troubleshooting UI)
pairedAccessoryInfos[(id: UUID, name: String)]Returns paired accessories from AccessorySetupKit
lastConnectedDeviceIDUUID?Last device ID stored for auto-reconnect
onConnectionReady(() async -> Void)?Called when connection is ready and services are available

SyncCoordinator (public, actor)

File: MC1Services/Sources/MC1Services/Sync/SyncCoordinator.swift (split across Sync/SyncCoordinator+Sync.swift, +MessageHandlers.swift, +ReactionHandlers.swift, +HandlerHelpers.swift)

Orchestrates data synchronization between the MeshCore device and local database through three phases.

Sync Phases

public enum SyncPhase: Sendable, Equatable {
    case contacts   // Phase 1: Sync contacts from device
    case channels   // Phase 2: Sync channel configurations
    case messages   // Phase 3: Poll pending messages
}

Sync State

enum SyncState: Sendable, Equatable {  // internal, not public
    case idle
    case syncing(progress: SyncProgress)
    case synced
    case failed(SyncCoordinatorError)
}

Key Methods

MethodDescription
performFullSync(radioID:dataStore:contactService:channelService:messagePollingService:...) async throws -> FullSyncResultExecutes contacts → channels → messages sync (internal)
onConnectionEstablished(radioID:dependencies:...) async throws -> FullSyncResultCalled after a connection; wires handlers and syncs (internal)
setSyncActivityCallbacks(onStarted:onEnded:onPhaseChanged:) asyncSets UI callbacks for sync pill display

Connection Lifecycle

  1. Wire message handlers (before events arrive)
  2. Start event monitoring
  3. Perform full sync (contacts, channels, messages)
  4. Wire discovery handlers (for ongoing contact discovery)

MessageService (public, actor)

File: MC1Services/Sources/MC1Services/Services/MessageService.swift (sends split across MessageService+SendDM.swift, +SendChannel.swift, +SendHelpers.swift; ACK tracking in MessageService+ACK.swift)

Handles message sending with automatic retry logic, flood routing fallback, and ACK tracking.

Configuration

struct MessageServiceConfig: Sendable {  // internal; defined in MessageServiceConfig.swift
    let floodFallbackOnRetry: Bool        // Use flood on manual retry (default: true)
    let maxAttempts: Int                  // Total attempts (default: 5; capped at 5 = 4 direct + 1 flood)
    let maxFloodAttempts: Int             // Max flood attempts (default: 1)
    let floodAfter: Int                   // Switch to flood after N direct attempts (default: 4)
    let minTimeout: TimeInterval          // Minimum timeout seconds (default: 0)
    let triggerPathDiscoveryAfterFlood: Bool // Trigger path discovery after a successful flood
    let ackGiveUpWindow: TimeInterval     // Give-up floor for the ACK deadline on fast presets
    let poolBackoff: PoolBackoffConfig    // In-loop pool-exhaustion backoff tuning
}

Messaging Methods

MethodDescription
sendMessageWithRetry(text:to:...) async throws -> MessageDTOSends with auto-retry and flood fallback
sendDirectMessage(text:to:...) async throws -> MessageDTOSingle attempt send
sendChannelMessage(text:channelIndex:...) async throws -> (id: UUID, timestamp: UInt32)Broadcasts to channel
resendDirectMessage(messageID:to:) async throws -> MessageDTOManual retry of a failed direct message
resendChannelMessage(messageID:preserveTimestamp:) async throws -> UInt32Manual retry of a failed channel message (returns the timestamp)

Event Monitoring

MethodDescription
startEventMonitoring()Starts monitoring session events to process message acknowledgements
stopEventMonitoring()Stops monitoring session events

ACK Tracking

MethodDescription
startAckExpiryChecking(interval:)Starts periodic expired ACK checks (default: 5s; wired on connect via ServiceContainer.startEventMonitoring)
stopAckExpiryChecking()Stops background ACK checking
checkExpiredAcks() async throwsMarks expired ACKs' messages as .failed and pushes codes into the late-ACK ring
failAllPendingMessages() async throwsFails all pending messages that are awaiting ACK
stopAndFailAllPending() async throwsStops ACK checking and fails all pending messages atomically

Properties

PropertyTypeDescription
pendingAckCountIntCurrent number of pending ACKs being tracked
isAckExpiryCheckingActiveBoolWhether ACK expiry checking is currently active

Dependencies

The ContactService used for path management during retry is injected via MessageService's initializer (no public setter). Status updates flow through ChatCoordinator, MessageStatusEvent, and the PersistenceStore rather than per-callback handler setters on the service.

Retry Flow

  1. Direct routing for the first floodAfter attempts (using the contact's outbound path)
  2. Flood routing thereafter (broadcast to all nearby nodes), up to maxAttempts (capped at 5 = 4 direct + 1 flood)
  3. Returns immediately when ACK received
  4. Marks failed if all attempts exhausted

ContactService (public, actor)

File: MC1Services/Sources/MC1Services/Services/ContactService.swift

Manages discovery, synchronization, and storage of mesh contacts.

Sync Methods

MethodDescription
syncContacts(radioID:since:) async throws -> ContactSyncResultIncremental or full contact sync

Contact Management

MethodDescription
getContact(radioID:publicKey:) async throws -> ContactDTO?Get a specific contact by public key from local database
addOrUpdateContact(radioID:contact:) async throwsAdds/updates contact on device and local store
removeContact(radioID:publicKey:) async throwsDeletes from device and local store

Path Discovery & Routing

MethodDescription
sendPathDiscovery(radioID:publicKey:) async throws -> MessageSentInfoInitiates route discovery
resetPath(radioID:publicKey:) async throwsResets routing, forces mesh rediscovery
setPath(radioID:publicKey:path:pathLength:) async throwsSet a specific path for a contact

Contact Sharing

MethodDescription
shareContact(publicKey:) async throwsShare a contact via zero-hop broadcast
exportContact(publicKey:) async throws -> StringExport a contact to a shareable URI
exportContactURI(name:publicKey:type:) -> StringBuild a shareable contact URI (static method)
importContact(cardData:) async throwsImport a contact from card data

Local Database Operations

MethodDescription
getContacts(radioID:) async throws -> [ContactDTO]Get all contacts for a device from local database
getConversations(radioID:) async throws -> [ContactDTO]Get conversations (contacts with messages) from local database
getContactByID(_:) async throws -> ContactDTO?Get a contact by ID from local database
updateContactPreferences(contactID:nickname:isBlocked:isFavorite:) async throwsUpdate local contact preferences

ChannelService (public, actor)

File: MC1Services/Sources/MC1Services/Services/ChannelService.swift

Manages group messaging channels and secure slot configuration.

Sync Methods

MethodDescription
syncChannels(radioID:maxChannels:usePipelinedRead:) async throws -> ChannelSyncResultSyncs all channel slot configurations (internal)

Channel CRUD Operations

MethodDescription
fetchChannel(index:) async throws -> ChannelInfo?Fetches a single channel from the device
setChannel(radioID:index:name:passphrase:) async throwsConfigures slot with passphrase (SHA-256 hashed)
setChannelWithSecret(radioID:index:name:secret:) async throwsSets a channel with a pre-computed secret
clearChannel(radioID:index:) async throwsResets a channel slot

Local Database Operations

MethodDescription
getChannels(radioID:) async throws -> [ChannelDTO]Gets all channels from local database for a device
getChannel(radioID:index:) async throws -> ChannelDTO?Gets a specific channel from local database
getActiveChannels(radioID:) async throws -> [ChannelDTO]Gets channels that have messages (for chat list)
clearChannelMessages(radioID:channelIndex:) async throwsDeletes local messages for a channel

Public Channel (Slot 0)

MethodDescription
setupPublicChannel(radioID:) async throwsInitializes default public channel on slot 0
hasPublicChannel(radioID:) async throws -> BoolChecks if the public channel exists locally

Static Utilities

MethodDescription
hashSecret(_:) -> DataHashes a passphrase into a 16-byte channel secret using SHA-256
validateSecret(_:) -> BoolValidates that a secret has the correct size

RemoteNodeService (public, actor)

File: MC1Services/Sources/MC1Services/Services/RemoteNodeService.swift

Queries remote mesh nodes using the binary protocol.

Session Management

MethodDescription
createSession(radioID:contact:) async throws -> RemoteNodeSessionDTOCreate a new session for a remote node
removeSession(id:publicKey:) async throwsRemove a session and its associated data
hasPassword(forContact:) async -> BoolCheck if a password is stored for a contact's public key
storePassword(_:forNodeKey:) async throwsStore a password for a remote node

Login & Authentication

MethodDescription
login(sessionID:password:pathLength:) async throws -> LoginResultLogin to a remote node (works for both room servers and repeaters)
logout(sessionID:) async throwsExplicitly logout from a remote node

Event Monitoring

MethodDescription
startEventMonitoring()Start monitoring MeshCore events for login results
stopEventMonitoring()Stop monitoring events

Keep-Alive (Room Servers)

MethodDescription
sendKeepAlive(sessionID:) async throwsSend keep-alive (for manual refresh)

Remote Node Queries

MethodDescription
requestStatus(sessionID:) async throws -> StatusResponseGets battery, uptime, SNR from remote
requestTelemetry(sessionID:) async throws -> TelemetryResponseGets sensor telemetry from remote
requestHistorySync(sessionID:) async throwsRequest message history from a room server

CLI Commands

MethodDescription
sendCLICommand(sessionID:command:) async throws -> StringSend a CLI command to a remote node (admin only)

Connection Management

MethodDescription
disconnect(sessionID:) asyncMark session as disconnected without sending logout
handleBLEReconnection(sessionIDs:) asyncCalled when BLE connection is re-established
stopAllKeepAlives()Stop all keep-alive timers (call on app termination)

Handlers

PropertyTypeDescription
keepAliveResponseHandler(@Sendable (UUID, Int) async -> Void)?Handler for keep-alive ACK responses

Note: Neighbor fetching is performed via MeshCoreSession.fetchAllNeighbours() directly.


PersistenceStore (public, @ModelActor actor)

File: MC1Services/Sources/MC1Services/Services/PersistenceStore.swift

Type alias: DataStore = PersistenceStore

The unified interface for SwiftData persistence, shared across all services.

Responsibilities

  • CRUD operations for Device, Contact, Message, Channel, RemoteNodeSession, RoomMessage models
  • Thread-safe access via actor model
  • Uses DTOs for cross-boundary data transfer

Device Operations

MethodDescription
fetchDevices() throws -> [DeviceDTO]Fetch all devices
fetchDevice(id:) throws -> DeviceDTO?Fetch a device by ID
fetchActiveDevice() throws -> DeviceDTO?Fetch the active device
saveDevice(_:) throwsSave or update a device
setActiveDevice(id:) throwsSet a device as active (deactivates others)
deleteDevice(id:) throwsDelete a device and all its associated data

Contact Operations

MethodDescription
fetchContacts(radioID:) throws -> [ContactDTO]Fetch all contacts for a device
fetchContact(id:) throws -> ContactDTO?Fetch a contact by ID
fetchContact(radioID:publicKey:) throws -> ContactDTO?Fetch a contact by public key
fetchConversations(radioID:) throws -> [ContactDTO]Fetch contacts with messages
saveContact(_:) throwsSave or update a contact
saveContact(radioID:from:) throws -> UUIDSave contact from ContactFrame
deleteContact(id:) throwsDelete a contact
updateContactLastMessage(contactID:date:) throwsUpdate contact's last message date

Message Operations

MethodDescription
fetchMessages(contactID:) throws -> [MessageDTO]Fetch all messages for a contact
fetchMessages(radioID:channelIndex:) throws -> [MessageDTO]Fetch all messages for a channel
fetchMessage(id:) throws -> MessageDTO?Fetch a message by ID
saveMessage(_:) throwsSave or update a message
deleteMessage(id:) throwsDelete a message
updateMessageStatus(id:status:) throwsUpdate message delivery status
updateMessageAck(id:ackCode:status:roundTripTime:) throwsUpdate message ACK code, status, and round-trip time
updateMessageRetryStatus(id:status:retryAttempt:maxRetryAttempts:) throwsUpdate message retry status
updateMessageHeardRepeats(id:heardRepeats:) throwsUpdate message heard repeats count
markMessageAsRead(id:) throwsMark a single message as read by message ID

Channel Operations

MethodDescription
fetchChannels(radioID:) throws -> [ChannelDTO]Fetch all channels for a device
fetchChannel(id:) throws -> ChannelDTO?Fetch a channel by ID
fetchChannel(radioID:index:) throws -> ChannelDTO?Fetch a channel by index
saveChannel(_:) throwsSave or update a channel
saveChannel(radioID:from:) throws -> UUIDSave channel from ChannelInfo
deleteChannel(id:) throwsDelete a channel
updateChannelLastMessage(channelID:date:) throwsUpdate channel's last message date

RemoteNodeSession Operations

MethodDescription
fetchRemoteNodeSession(id:) throws -> RemoteNodeSessionDTO?Fetch a session by ID
fetchRemoteNodeSession(publicKey:) throws -> RemoteNodeSessionDTO?Fetch a session by public key
fetchRemoteNodeSessionByPrefix(_:) throws -> RemoteNodeSessionDTO?Fetch a session by public key prefix
fetchConnectedRemoteNodeSessions() throws -> [RemoteNodeSessionDTO]Fetch all connected sessions
saveRemoteNodeSessionDTO(_:) throwsSave or update a session
updateRemoteNodeSessionConnection(id:isConnected:permissionLevel:) throwsUpdate session connection state
deleteRemoteNodeSession(id:) throwsDelete a session

Static Methods

MethodDescription
createContainer(inMemory:) throws -> ModelContainerCreates a ModelContainer for the app

Data Transfer Objects

MessageDTO (public, struct)

File: MC1Services/Sources/MC1Services/Models/Message.swift (search for public struct MessageDTO)

A sendable snapshot of Message for cross-actor transfers. The DTO evolves as features are added (link previews, reactions, mentions, etc.), so this doc intentionally describes the shape at a high level.

Key fields you can rely on:

  • Identity and routing: id, deviceID, contactID or channelIndex
  • Content and timing: text, timestamp, createdAt, senderTimestamp (when available)
  • Delivery metadata: direction, status, textType, ackCode, roundTripTime, retryAttempt, maxRetryAttempts
  • RF / mesh metadata: pathLength, pathNodes, snr, heardRepeats, sendCount
  • Sender identity: senderKeyPrefix, senderNodeName
  • UI flags: isRead, containsSelfMention, mentionSeen, timestampCorrected
  • Rich content caches: link preview fields and reactionSummary

ContactDTO (public, struct)

File: MC1Services/Sources/MC1Services/Models/Contact.swift (search for public struct ContactDTO)

A sendable snapshot of Contact for cross-actor transfers.

Notes:

  • latitude and longitude are not optional. Treat 0,0 as "unknown" and use ContactDTO.hasLocation (computed) where available.
  • Favorites are synced with the device via the flags byte (bit 0) and cached as isFavorite.

Computed Properties

PropertyTypeDescription
typeContactTypeComputed from typeRawValue
displayNameStringReturns nickname if set, otherwise name
publicKeyPrefixDataFirst 6 bytes of public key

DeviceDTO (public, struct)

File: MC1Services/Sources/MC1Services/Models/Device.swift (search for public struct DeviceDTO)

A sendable snapshot of Device for cross-actor transfers. The DTO carries radioID (the data-partition key) in addition to id, and gains fields over time (OCV settings, flood scope, connection methods, known regions, repeater pre-repeat radio config), so the table below lists the core fields rather than the full set.

PropertyTypeDescription
idUUIDDevice identifier
publicKeyDataDevice public key
nodeNameStringDevice node name
firmwareVersionUInt8Firmware version number
firmwareVersionStringStringFirmware version string
manufacturerNameStringManufacturer name
buildDateStringFirmware build date
maxContactsUInt16Maximum contacts supported
maxChannelsUInt8Maximum channels supported
frequencyUInt32Radio frequency (kHz)
bandwidthUInt32Radio bandwidth (Hz)
spreadingFactorUInt8LoRa spreading factor
codingRateUInt8LoRa coding rate
txPowerInt8Transmit power (dBm)
maxTxPowerInt8Maximum transmit power (dBm)
latitudeDoubleDevice location latitude
longitudeDoubleDevice location longitude
blePinUInt32BLE pairing PIN
manualAddContactsBoolManual contact add mode
multiAcksUInt8Multiple ACKs mode
telemetryModeBaseUInt8Base telemetry mode
telemetryModeLocUInt8Location telemetry mode
telemetryModeEnvUInt8Environment telemetry mode
advertLocationPolicyUInt8Advertisement location policy
lastConnectedDateLast connection timestamp
lastContactSyncUInt32Last contact sync timestamp
isActiveBoolActive status

Computed Properties

PropertyTypeDescription
publicKeyPrefixDataFirst 6 bytes of public key

ChannelDTO (public, struct)

File: MC1Services/Sources/MC1Services/Models/Channel.swift (search for public struct ChannelDTO)

A sendable snapshot of Channel for cross-actor transfers. Core fields:

PropertyTypeDescription
idUUIDLocal identifier
radioIDUUIDAssociated device (data-partition key)
indexUInt8Slot number (0-7)
nameStringChannel name
secretDataChannel encryption secret (16 bytes)
isEnabledBoolChannel enabled status
lastMessageDateDate?Most recent message date
unreadCountIntUnread messages
unreadMentionCountIntUnread @-mentions
notificationLevelNotificationLevelPer-channel notification preference
isFavoriteBoolFavorite flag
floodScopeModeRawValueStringFlood-scope mode (raw)

Computed Properties

PropertyTypeDescription
isPublicChannelBoolTrue if this is slot 0 (the public channel slot)

Additional Services

ServiceTypeDescription
MessagePollingServiceinternal, actorPolls device for pending messages, routes to handlers
SettingsServicepublic, actorManages device settings (name, location, radio)
AdvertisementServicepublic, actorSends advertisements to mesh
RoomServerServicepublic, actorHandles room server messaging
RepeaterAdminServicepublic, actorAdmin commands for repeater nodes
BinaryProtocolServicepublic, actorBinary protocol encoding/decoding
KeychainServiceinternal, actorSecure credential storage
NotificationServicepublic, @MainActor, @Observable classLocal notification scheduling
ReactionServicepublic, actorParses and persists emoji reactions
RxLogServicepublic, actorCaptures RF packets for network diagnostics
PersistentLoggerpublic, structWrites to OSLog and enqueues buffered debug log entries
DebugLogBufferpublic, actorBatches debug logs and writes to SwiftData
CommandAuditLoggerinternal, actorStructured logging of remote-node operations (login, status, telemetry, CLI, keep-alive) for diagnostics
DeviceServicepublic, actorDevice update callback and OCV settings persistence
HeardRepeatsServicepublic, actorTracks channel-message repeat counts for propagation analysis
ServiceContainer@MainActor, public final classHolds all service instances

New Services

RxLogService (public, actor)

File: MC1Services/Sources/MC1Services/Services/RxLogService.swift

Captures and stores RF packet log entries for network diagnostics.

Methods:

MethodDescription
startEventMonitoring(radioID:)Starts capturing RF packets from transport events
stopEventMonitoring()Stops packet capture
process(_:) asyncProcesses a parsed RX-log packet into a stored entry
loadExistingEntries() async -> [RxLogEntryDTO]Loads stored log entries
decryptEntry(_:) -> RxLogEntryDTODecrypts a stored entry's payload
clearEntries() asyncClears all log entries

Capture Features:

  • Real-time packet monitoring
  • Automatic metadata extraction (RSSI, SNR, packet type)
  • SwiftData persistence

PersistentLogger (public, struct)

File: MC1Services/Sources/MC1Services/Services/PersistentLogger.swift

Writes to OSLog and enqueues debug log entries into DebugLogBuffer for persistence.

Methods:

MethodDescription
debug(_:)Logs a debug message
info(_:)Logs an info message
notice(_:)Logs a notice message
warning(_:)Logs a warning message
error(_:)Logs an error message
fault(_:)Logs a fault message

DebugLogBuffer (public, actor)

File: MC1Services/Sources/MC1Services/Services/DebugLogBuffer.swift

Buffered log sink that batches debug log entries and writes to SwiftData.

Methods:

MethodDescription
append(_:)Adds a debug log entry to the buffer
flush()Flushes buffered entries to SwiftData
shutdown()Cancels scheduled flush and persists remaining entries

Buffer Features:

  • Batched persistence (flush interval: 5 seconds or 50 entries)
  • Thread-safe actor isolation

CommandAuditLogger (internal, actor)

File: MC1Services/Sources/MC1Services/Services/CommandAuditLogger.swift

Structured Logger-based logging of remote-node operations for diagnostics. It logs events rather than persisting an auditable history; there is no CommandAuditEntryDTO and no query API.

Methods (selection):

MethodDescription
logLoginRequest(target:publicKey:pathLength:)Logs a remote-node login attempt
logLoginSuccess(target:publicKey:isAdmin:)Logs a successful login
logLoginFailed(target:publicKey:reason:)Logs a failed login
logCLICommand(publicKey:command:)Logs a CLI command sent to a node
logCLIResponse(publicKey:response:)Logs a CLI command response
logStatusRequest(target:publicKey:) / logTelemetryRequest(target:publicKey:)Logs status/telemetry queries
logKeepAlive(target:publicKey:)Logs a keep-alive

DeviceService (public, actor)

File: MC1Services/Sources/MC1Services/Services/DeviceService.swift

Wires a device-update callback and persists OCV battery-curve settings. General device fetches go through PersistenceStore directly.

Methods:

MethodDescription
setDeviceUpdateCallback(_:)Registers a callback invoked when the device DTO changes
updateOCVSettings(deviceID:preset:customArray:) async throwsPersists the OCV preset and custom curve for a device

HeardRepeatsService (public, actor)

File: MC1Services/Sources/MC1Services/Services/HeardRepeatsService.swift

Tracks message repeat counts for channel message propagation analysis.

Methods:

MethodDescription
configure(radioID:localNodeName:)Configures the service for the active radio
events() -> AsyncStream<HeardRepeatEvent>Stream of heard-repeat events for UI updates
processForRepeats(_:) async -> Int?Counts a repeat from a parsed RX-log entry, returning the new count
refreshRepeats(for:) async -> [MessageRepeatDTO]Returns the recorded repeats for a message

Repeats Features:

  • Real-time tracking of message propagation
  • Stored with Message model
  • Used for displaying "Heard by X" in channel messages

Note: ElevationService and LocationService are app-layer utilities in MeshCore One (not part of the MC1Services package). See docs/api/MeshCore One.md for app-layer references.


New Models

RxLogEntryDTO (public, struct)

File: MC1Services/Sources/MC1Services/Models/RxLogEntry.swift

A sendable snapshot of RF packet log entry.

Properties:

PropertyTypeDescription
idUUIDUnique identifier
radioIDUUIDAssociated device (data-partition key)
receivedAtDateWhen packet was received
snrDouble?Signal-to-noise ratio in dB
rssiInt?Received signal strength indicator in dBm
routeTypeRouteTypeRoute type (flood vs. direct)
payloadTypePayloadTypeDecoded packet payload type
pathLengthUInt8Routing path length
pathNodesDataRouting path bytes
packetPayloadDataDecoded payload bytes
rawPayloadDataRaw on-air payload bytes
packetHashStringPacket hash
decryptStatusDecryptStatusWhether the payload decrypted

Sender/recipient key prefixes are exposed as the computed senderPrefix / recipientPrefix properties.

DebugLogEntryDTO (public, struct)

File: MC1Services/Sources/MC1Services/Models/DebugLogEntry.swift

A sendable snapshot of debug log entry.

Properties:

PropertyTypeDescription
idUUIDUnique identifier
timestampDateWhen log was created
levelDebugLogLevelSeverity: .debug, .info, .notice, .warning, .error, .fault
subsystemStringLogging subsystem identifier
categoryStringLogging category
messageStringLog message

DiscoveredNodeDTO (public, struct)

File: MC1Services/Sources/MC1Services/Models/DiscoveredNode.swift

A sendable snapshot of a discovered node (advertisement cache for Discovery).

Properties:

PropertyTypeDescription
idUUIDUnique identifier
radioIDUUIDAssociated device (data-partition key)
publicKeyData32-byte public key
nameStringAdvertised node name
typeRawValueUInt8Node type raw value
lastHeardDateLast advertisement timestamp (local)
lastAdvertTimestampUInt32Firmware advertisement timestamp
latitudeDoubleNode latitude
longitudeDoubleNode longitude
outPathLengthUInt8Routing path length
outPathDataRouting path data

ReactionDTO (public, struct)

File: MC1Services/Sources/MC1Services/Models/Reaction.swift

A sendable snapshot of a reaction on a message.

Properties:

PropertyTypeDescription
idUUIDUnique identifier
messageIDUUIDTarget message ID
emojiStringReaction emoji
senderNameStringSender display name
messageHashStringReaction hash (Crockford Base32)
rawTextStringRaw wire-format text
receivedAtDateReceived timestamp
channelIndexUInt8?Channel index (nil for DM)
contactIDUUID?Contact ID (DM only)
radioIDUUIDAssociated device (data-partition key)

ElevationSample (public, struct)

File: MC1Services/Sources/MC1Services/RF/ElevationSample.swift

Represents a terrain elevation data point.

Properties:

PropertyTypeDescription
coordinateCLLocationCoordinate2DGeographic coordinates
elevationDoubleElevation in meters above sea level
distanceFromAMetersDoubleDistance from point A in meters

OCVPreset (public, enum)

File: MC1Services/Sources/MC1Services/Models/OCVPreset.swift

String-raw-valued, CaseIterable, Codable, Sendable enum of built-in Open Circuit Voltage (OCV) battery discharge curve presets. It is an enum, not a DTO struct.


See Also