Class MissionClient

Namespace
MavNet.PX4.Missions
Assembly
MavNet.PX4.dll

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

connection IMavlinkConnection

Transport — subscribes to its mission events for the lifetime of this client.

targetSystem byte

Sender system id we accept inbound mission messages from, and the target on outbound.

targetComponent byte

Sender component id we accept inbound mission messages from, and the target on outbound.

missionType MavMissionType

Which on-vehicle plan this client manages.

defaultTimeout TimeSpan?

Per-message timeout. Defaults to 1500 ms (spec).

itemTimeout TimeSpan?

Inner item-loop timeout. Defaults to 250 ms (spec).

maxRetries int

Max retries per message before failing as Timeout. Defaults to 5 (spec).

logger ILogger

Optional. Null = no logging.

Properties

DefaultTimeout

Default per-message timeout (1500 ms per spec unless overridden).

public TimeSpan DefaultTimeout { get; }

Property Value

TimeSpan

IsBusy

True iff a transaction (upload, download, …) is currently in flight.

public bool IsBusy { get; }

Property Value

bool

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

TimeSpan

MaxRetries

Max retries per message (5 per spec unless overridden).

public int MaxRetries { get; }

Property Value

int

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

ct CancellationToken

Cancellation. On firing, completes Cancelled.

Returns

Task<MissionClearResult>

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

ct CancellationToken

Cancellation. On firing, the transaction completes with Cancelled; whatever partial items were collected are discarded (Items is empty).

Returns

Task<MissionDownloadResult>

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

items IReadOnlyList<MissionItem>

Items in order. Count must fit in a ushort. An empty list is accepted (the vehicle treats MISSION_COUNT=0 as a clear).

ct CancellationToken

Cancellation. 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

Task<MissionUploadResult>

Exceptions

InvalidOperationException

Another transaction is already in flight.

ObjectDisposedException

This client has been disposed.

ArgumentNullException

If items is null.

ArgumentException

If items exceeds ushort.MaxValue.