Class MissionClient
Implements the MAVLink mission-protocol upload and download state machines for
one (target, MavNet.Protocol.Generated.Enums.MavMissionType) pair on top of an
IMavlinkConnection. One MissionClient handles one
mission type (waypoints, fence, or rally) — Vehicle owns one per type so the
three transactions can run independently per spec.
Upload. Caller invokes UploadAsync(IReadOnlyList<MissionItem>, CancellationToken). We send
MISSION_COUNT, then for each MISSION_REQUEST_INT (or its
deprecated MISSION_REQUEST sibling that ArduPilot still emits) we reply
with a MISSION_ITEM_INT. After the final item the vehicle answers with
MISSION_ACK, which terminates the transaction.
Download. Caller invokes DownloadAsync(CancellationToken). We send
MISSION_REQUEST_LIST, the vehicle responds with MISSION_COUNT
(carrying the on-vehicle opaque_id), then we send a
MISSION_REQUEST_INT per item in order and collect each
MISSION_ITEM_INT reply. After the final item we send a final
MISSION_ACK(MAV_MISSION_ACCEPTED) per spec to close the transaction.
Timing. Per the MAVLink spec: 1500 ms default timeout, 250 ms for the inner item loop, max 5 retries. Defaults are baked in but all three are constructor-injectable so tests stay sub-second.
Out-of-sequence is not an error. If the vehicle re-requests an
earlier seq during upload, we re-answer with that item rather than abort. If
the vehicle answers with an unexpected seq during download, we just ignore it
and let the watchdog re-request. Per spec only timeout exhaustion and a
non-Accepted MISSION_ACK cause a transaction to fail.
Threading. Inbound events fire on the connection's receive thread.
All mutable state is guarded by an internal lock; the lock window only covers
the state mutation, never the awaiter's continuation (the result Task
uses RunContinuationsAsynchronously).
Single-flight. Only one transaction may be in flight per MissionClient, regardless of direction. A concurrent UploadAsync(IReadOnlyList<MissionItem>, CancellationToken) or DownloadAsync(CancellationToken) throws InvalidOperationException.
public sealed class MissionClient : IDisposable
- Inheritance
-
MissionClient
- Implements
- Inherited Members
Constructors
MissionClient(IMavlinkConnection, byte, byte, MavMissionType, TimeSpan?, TimeSpan?, int, ILogger?)
Create a client bound to one target and one mission type.
public MissionClient(IMavlinkConnection connection, byte targetSystem, byte targetComponent, MavMissionType missionType = MavMissionType.Mission, TimeSpan? defaultTimeout = null, TimeSpan? itemTimeout = null, int maxRetries = 5, ILogger? logger = null)
Parameters
connectionIMavlinkConnectionTransport — subscribes to its mission events for the lifetime of this client.
targetSystembyteSender system id we accept inbound mission messages from, and the target on outbound.
targetComponentbyteSender component id we accept inbound mission messages from, and the target on outbound.
missionTypeMavMissionTypeWhich on-vehicle plan this client manages.
defaultTimeoutTimeSpan?Per-message timeout. Defaults to 1500 ms (spec).
itemTimeoutTimeSpan?Inner item-loop timeout. Defaults to 250 ms (spec).
maxRetriesintMax retries per message before failing as Timeout. Defaults to 5 (spec).
loggerILoggerOptional. Null = no logging.
Properties
DefaultTimeout
Default per-message timeout (1500 ms per spec unless overridden).
public TimeSpan DefaultTimeout { get; }
Property Value
IsBusy
True iff a transaction (upload, download, …) is currently in flight.
public bool IsBusy { get; }
Property Value
ItemTimeout
Item-request timeout (250 ms per spec unless overridden) — used for the
inner request/response loop after the first MISSION_REQUEST_INT arrives.
public TimeSpan ItemTimeout { get; }
Property Value
MaxRetries
Max retries per message (5 per spec unless overridden).
public int MaxRetries { get; }
Property Value
MissionType
The mission type this client handles.
public MavMissionType MissionType { get; }
Property Value
- MavMissionType
Methods
ClearAsync(CancellationToken)
Clear the on-vehicle plan for this client's MissionType.
Sends MISSION_CLEAR_ALL and awaits MISSION_ACK. Resolves when
the vehicle ACKs, after retry/timeout exhaustion, on cancellation, or on disposal.
public Task<MissionClearResult> ClearAsync(CancellationToken ct = default)
Parameters
ctCancellationTokenCancellation. On firing, completes Cancelled.
Returns
Exceptions
- InvalidOperationException
Another transaction is already in flight.
- ObjectDisposedException
This client has been disposed.
Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()
DownloadAsync(CancellationToken)
Download the on-vehicle plan for this client's MissionType.
Resolves when the final MISSION_ITEM_INT arrives and we've sent the
closing MISSION_ACK(Accepted), after retry/timeout exhaustion, on
cancellation, or on disposal.
public Task<MissionDownloadResult> DownloadAsync(CancellationToken ct = default)
Parameters
ctCancellationTokenCancellation. On firing, the transaction completes with Cancelled; whatever partial items were collected are discarded (Items is empty).
Returns
Exceptions
- InvalidOperationException
Another transaction is already in flight.
- ObjectDisposedException
This client has been disposed.
UploadAsync(IReadOnlyList<MissionItem>, CancellationToken)
Upload items to the target vehicle for this client's
MissionType. Resolves when the vehicle responds with
MISSION_ACK, after retry/timeout budget exhaustion, on cancellation,
or on disposal.
public Task<MissionUploadResult> UploadAsync(IReadOnlyList<MissionItem> items, CancellationToken ct = default)
Parameters
itemsIReadOnlyList<MissionItem>Items in order.
Countmust fit in a ushort. An empty list is accepted (the vehicle treatsMISSION_COUNT=0as a clear).ctCancellationTokenCancellation. On firing, the transaction completes with Cancelled; the vehicle may be left in a partial-upload state and a follow-up clear/re-upload is advisable.
Returns
Exceptions
- InvalidOperationException
Another transaction is already in flight.
- ObjectDisposedException
This client has been disposed.
- ArgumentNullException
If
itemsis null.- ArgumentException
If
itemsexceedsushort.MaxValue.