Class MrpProtocol
- Namespace
- AppleTvControlLibrary.Mrp.Protocol
- Assembly
- AppleTvControlLibrary.Mrp.dll
Protocol logic related to MRP: connects, performs the initial DEVICE_INFORMATION exchange, enables encryption via pair-verify, sends the post-encryption bootstrap messages, and provides request/response correlation plus unsolicited-message dispatch on top of the underlying IMrpFrameConnection.
public sealed class MrpProtocol : IMrpConnectionListener, IDisposable
- Inheritance
-
MrpProtocol
- Implements
- Inherited Members
Remarks
This type has no socket I/O of its own; a caller supplies AsyncSender to
transmit framed bytes and feeds inbound bytes to the underlying IMrpFrameConnection
(via Connection), mirroring the transport-agnostic design already used by
AppleTv.Companion's CompanionProtocol.
Constructors
MrpProtocol(IMrpFrameConnection, SrpAuthHandler, MrpInfoSettings)
Initializes a new instance of the MrpProtocol class.
public MrpProtocol(IMrpFrameConnection connection, SrpAuthHandler srp, MrpInfoSettings info)
Parameters
connectionIMrpFrameConnectionThe underlying framed connection. May be an AirPlay-tunneled connection, or historically the retired raw-TCP
MrpConnection(seearchive/mrp-tcp-transport).srpSrpAuthHandlerThe SRP handler used for pair-verify and key derivation.
infoMrpInfoSettingsClient information reported in the initial DEVICE_INFORMATION message.
Properties
AsyncSender
Gets or sets the asynchronous callback that transmits fully-built frames.
public Func<byte[], Task>? AsyncSender { get; set; }
Property Value
Connection
Gets the underlying connection, so a transport can feed it received bytes.
public IMrpFrameConnection Connection { get; }
Property Value
Credentials
Gets or sets the credentials used to enable encryption. Set externally when reusing
previously-paired credentials rather than pairing fresh (mirrors pyatv checking
self.service.credentials). pyatv/protocols/mrp/protocol.py — line 137-140 as of pyatv 0.18.0
public HapCredentials? Credentials { get; set; }
Property Value
Listener
Gets or sets the listener notified when an unsolicited message is dispatched.
public IMrpProtocolListener? Listener { get; set; }
Property Value
PowerState
Gets the last-known device power state, derived from DeviceInfoMessage.logicalDeviceCount
on every DEVICE_INFO_MESSAGE / DEVICE_INFO_UPDATE_MESSAGE seen so far.
public MrpPowerState PowerState { get; }
Property Value
ResponseTimeout
Gets or sets how long to wait for a response before SendAndReceiveAsync(ProtocolMessage, bool, CancellationToken) throws a MrpProtocolException.
public TimeSpan ResponseTimeout { get; set; }
Property Value
State
Gets the current protocol state.
public MrpProtocolState State { get; }
Property Value
Methods
Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()
MessageReceived(byte[])
A complete, decrypted message was received from the device.
public void MessageReceived(byte[] data)
Parameters
databyte[]The serialized protobuf message bytes.
SendAndReceiveAsync(ProtocolMessage, bool, CancellationToken)
Send a message and wait for a response.
public Task<ProtocolMessage> SendAndReceiveAsync(ProtocolMessage message, bool generateIdentifier = true, CancellationToken cancellationToken = default)
Parameters
messageProtocolMessageThe message to send.
generateIdentifierboolWhether to generate and set a new
identifieron the message before sending (some messages, like crypto pairing, never carry one, and are instead correlated by message type since only one such exchange can ever be outstanding).cancellationTokenCancellationTokenA token that cancels waiting to send or receive a response.
Returns
- Task<ProtocolMessage>
The response message received from the device.
SendAsync(ProtocolMessage, CancellationToken)
Send a message and expect no response.
public Task SendAsync(ProtocolMessage message, CancellationToken cancellationToken = default)
Parameters
messageProtocolMessageThe message to send.
cancellationTokenCancellationTokenA token that cancels waiting to send.
Returns
StartAsync(bool, CancellationToken)
Send the initial DEVICE_INFORMATION message, enable encryption if credentials are set, and run the post-encryption bootstrap sequence.
public Task StartAsync(bool skipInitialMessages = false, CancellationToken cancellationToken = default)
Parameters
skipInitialMessagesboolIf true, stop right after DEVICE_INFORMATION (used by proxy-style reuse of a protocol object). pyatv/protocols/mrp/protocol.py — line 154-155 as of pyatv 0.18.0
cancellationTokenCancellationTokenA token that cancels the bootstrap exchanges.
Returns
Stop()
Disconnect from the device, failing any outstanding requests.
public void Stop()
Events
PowerStateChanged
Raised when PowerState changes as a result of an inbound DEVICE_INFO_MESSAGE or DEVICE_INFO_UPDATE_MESSAGE. Carries the previous and new power state, in that order.
public event Action<MrpPowerState, MrpPowerState>? PowerStateChanged
Event Type
RawMessageReceived
Raised for every inbound message, before correlation/dispatch, carrying the raw message type number and full serialized payload.
public event Action<int, byte[]>? RawMessageReceived
Event Type
Remarks
This is a diagnostic-only hook, not a port of anything in pyatv. Its purpose is to make
message types absent from the vendored pyatv 0.18.0 .proto set observable instead of
silently dropped: ProtocolMessage.Type declares SET_READY_STATE_MESSAGE = 36
and UPDATE_ACTIVE_SYSTEM_ENDPOINT_MESSAGE = 77 with no corresponding extension
message/field anywhere in the tree, and the enum itself skips 13, 14 and 45 entirely, so
pyatv has no name — and therefore no handler — for whatever Apple sends under those numbers.
Listener/IMrpProtocolListener only ever surfaces
ProtocolMessage instances decoded against Registry,
which is sufficient for known extension fields but does not by itself make an unnamed type
number easy to spot; this event exists purely so a consumer can log every
(type, raw bytes) pair unconditionally while investigating unknown wire traffic.