1use crate::VersionInfo;
5use bitfield_struct::bitfield;
6use hvdef::Vtl;
7use inspect::Inspect;
8use mesh::payload::Protobuf;
9use open_enum::open_enum;
10use std::mem::size_of;
11use std::ops::BitAnd;
12use std::ops::BitAndAssign;
13use std::ops::BitOr;
14use std::ops::Deref;
15use std::ops::DerefMut;
16use thiserror::Error;
17use zerocopy::FromBytes;
18use zerocopy::FromZeros;
19use zerocopy::Immutable;
20use zerocopy::IntoBytes;
21use zerocopy::KnownLayout;
22use zerocopy::Unalign;
23
24#[macro_use]
25mod macros;
26
27type Guid = guid::Guid;
28
29pub const VMBUS_MESSAGE_REDIRECT_CONNECTION_ID: u32 = 0x800074;
30
31pub const STATUS_SUCCESS: i32 = 0;
32pub const STATUS_UNSUCCESSFUL: i32 = 0x8000ffff_u32 as i32;
33pub const STATUS_CONNECTION_REFUSED: i32 = 0xc0000236_u32 as i32;
34
35pub const HEADER_SIZE: usize = size_of::<MessageHeader>();
36pub const MAX_MESSAGE_SIZE: usize = hvdef::HV_MESSAGE_PAYLOAD_SIZE;
37
38vmbus_messages! {
59 pub enum Message, MessageType {
60 1 OFFER_CHANNEL { OfferChannel V1 },
61 2 RESCIND_CHANNEL_OFFER { RescindChannelOffer V1 },
62 3 REQUEST_OFFERS { RequestOffers V1 },
63 4 ALL_OFFERS_DELIVERED { AllOffersDelivered V1 },
64 5 OPEN_CHANNEL {
65 OpenChannel2 Copper features:(guest_specified_signal_parameters | channel_interrupt_redirection),
66 OpenChannel V1
67 },
68 6 OPEN_CHANNEL_RESULT { OpenResult V1 },
69 7 CLOSE_CHANNEL { CloseChannel V1 },
70 8 GPADL_HEADER { GpadlHeader V1 },
71 9 GPADL_BODY { GpadlBody V1 },
72 10 GPADL_CREATED { GpadlCreated V1 },
73 11 GPADL_TEARDOWN { GpadlTeardown V1 },
74 12 GPADL_TORNDOWN { GpadlTorndown V1 },
75 13 REL_ID_RELEASED { RelIdReleased V1 },
76 14 INITIATE_CONTACT {
77 InitiateContact2 0 check_size:true,
81 InitiateContact 0
82 },
83 15 VERSION_RESPONSE {
84 VersionResponse3 0 check_size:true,
85 VersionResponse2 0 check_size:true,
86 VersionResponse 0
87 },
88 16 UNLOAD { Unload V1 },
89 17 UNLOAD_COMPLETE { UnloadComplete Win7 },
90 18 OPEN_RESERVED_CHANNEL { OpenReservedChannel Win10 },
91 19 CLOSE_RESERVED_CHANNEL { CloseReservedChannel 0 },
92 20 CLOSE_RESERVED_RESPONSE { CloseReservedChannelResponse Win10 },
93 21 TL_CONNECT_REQUEST {
94 TlConnectRequest2 Win10Rs5 check_size:true,
97 TlConnectRequest Win10
98 },
99 22 MODIFY_CHANNEL { ModifyChannel Win10Rs3_0 },
100 23 TL_CONNECT_REQUEST_RESULT { TlConnectResult Win10Rs3_0 },
101 24 MODIFY_CHANNEL_RESPONSE { ModifyChannelResponse Iron },
102 25 MODIFY_CONNECTION { ModifyConnection Copper features:modify_connection },
103 26 MODIFY_CONNECTION_RESPONSE { ModifyConnectionResponse Copper features:modify_connection },
104 27 PAUSE { Pause Copper features:pause_resume },
105 28 PAUSE_RESPONSE { PauseResponse Copper features:pause_resume },
106 29 RESUME { Resume Copper features:pause_resume },
107 }
108}
109
110#[derive(Debug, Error)]
112pub enum ParseError {
113 #[error("message too small: {0:?}")]
115 MessageTooSmall(Option<MessageType>),
116 #[error("unexpected or unsupported message type: {0:?}")]
119 InvalidMessageType(MessageType),
120}
121
122pub trait VmbusMessage: Sized {
124 const MESSAGE_TYPE: MessageType;
126
127 const MESSAGE_SIZE: usize = HEADER_SIZE + size_of::<Self>();
129}
130
131#[repr(C)]
133#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
134pub struct MessageHeader {
135 message_type: MessageType,
136 padding: u32,
137}
138
139impl MessageHeader {
140 pub fn new(message_type: MessageType) -> Self {
142 Self {
143 message_type,
144 padding: 0,
145 }
146 }
147
148 pub fn message_type(&self) -> MessageType {
149 self.message_type
150 }
151}
152
153#[derive(Inspect)]
154#[bitfield(u32)]
155#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
156pub struct FeatureFlags {
157 pub guest_specified_signal_parameters: bool, pub channel_interrupt_redirection: bool, pub modify_connection: bool, pub client_id: bool, pub confidential_channels: bool, pub pause_resume: bool, pub server_specified_monitor_pages: bool, pub gpa_pinning: bool, #[bits(24)]
198 _reserved: u32,
199}
200
201impl FeatureFlags {
202 pub fn contains(&self, other: FeatureFlags) -> bool {
204 self.into_bits() & other.into_bits() == other.into_bits()
205 }
206}
207
208impl BitAnd for FeatureFlags {
209 type Output = Self;
210
211 fn bitand(self, rhs: Self) -> Self::Output {
212 (self.into_bits() & rhs.into_bits()).into()
213 }
214}
215
216impl BitAndAssign for FeatureFlags {
217 fn bitand_assign(&mut self, rhs: Self) {
218 *self = (self.into_bits() & rhs.into_bits()).into()
219 }
220}
221
222impl BitOr for FeatureFlags {
223 type Output = Self;
224
225 fn bitor(self, rhs: Self) -> Self::Output {
226 (self.into_bits() | rhs.into_bits()).into()
227 }
228}
229
230#[repr(transparent)]
231#[derive(
232 Copy,
233 Clone,
234 Debug,
235 Eq,
236 PartialEq,
237 Ord,
238 PartialOrd,
239 Hash,
240 IntoBytes,
241 FromBytes,
242 Immutable,
243 KnownLayout,
244 Protobuf,
245)]
246#[mesh(package = "vmbus")]
247pub struct GpadlId(pub u32);
248
249#[repr(transparent)]
250#[derive(
251 Copy,
252 Clone,
253 Debug,
254 Eq,
255 Inspect,
256 PartialEq,
257 Ord,
258 PartialOrd,
259 Hash,
260 IntoBytes,
261 FromBytes,
262 Immutable,
263 KnownLayout,
264 Protobuf,
265)]
266#[inspect(transparent)]
267pub struct ChannelId(pub u32);
268
269pub struct ConnectionId(pub u32);
270
271impl ConnectionId {
272 pub fn new(channel_id: u32, vtl: Vtl, sint: u8) -> Self {
274 Self(channel_id | (sint as u32) << 12 | (vtl as u32) << 16)
275 }
276}
277
278#[repr(C)]
279#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
280pub struct InitiateContact {
281 pub version_requested: u32,
282 pub target_message_vp: u32,
283 pub interrupt_page_or_target_info: u64, pub parent_to_child_monitor_page_gpa: u64,
285 pub child_to_parent_monitor_page_gpa: u64,
286}
287
288#[repr(C)]
291#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
292pub struct InitiateContact2 {
293 pub initiate_contact: InitiateContact,
294 pub client_id: Guid,
295}
296
297impl From<InitiateContact> for InitiateContact2 {
298 fn from(value: InitiateContact) -> Self {
299 Self {
300 initiate_contact: value,
301 ..FromZeros::new_zeroed()
302 }
303 }
304}
305
306#[bitfield(u64)]
308pub struct TargetInfo {
309 pub sint: u8,
310 pub vtl: u8,
311 pub _padding: u16,
312 pub feature_flags: u32,
313}
314
315pub const fn make_version(major: u16, minor: u16) -> u32 {
316 ((major as u32) << 16) | (minor as u32)
317}
318
319#[repr(u32)]
320#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Inspect)]
321pub enum Version {
322 V1 = make_version(0, 13),
323 Win7 = make_version(1, 1),
324 Win8 = make_version(2, 4),
325 Win8_1 = make_version(3, 0),
326 Win10 = make_version(4, 0),
327 Win10Rs3_0 = make_version(4, 1),
328 Win10Rs3_1 = make_version(5, 0),
329 Win10Rs4 = make_version(5, 1),
330 Win10Rs5 = make_version(5, 2),
331 Iron = make_version(5, 3),
332 Copper = make_version(6, 0),
333}
334
335open_enum! {
336 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
338 pub enum ConnectionState: u8 {
339 SUCCESSFUL = 0,
340 FAILED_LOW_RESOURCES = 1,
341 FAILED_UNKNOWN_FAILURE = 2,
342 }
343}
344
345#[repr(C)]
346#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
347pub struct VersionResponse {
348 pub version_supported: u8,
349 pub connection_state: ConnectionState,
350 pub padding: u16,
351 pub selected_version_or_connection_id: u32,
352}
353
354#[repr(C)]
359#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
360pub struct VersionResponse2 {
361 pub version_response: VersionResponse,
362 pub supported_features: u32,
363}
364
365#[repr(C)]
368#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
369pub struct VersionResponse3 {
370 pub version_response2: VersionResponse2,
371 pub _padding: u32,
372 pub parent_to_child_monitor_page_gpa: u64,
374 pub child_to_parent_monitor_page_gpa: u64,
375}
376
377impl From<VersionResponse> for VersionResponse2 {
378 fn from(value: VersionResponse) -> Self {
379 Self {
380 version_response: value,
381 ..FromZeros::new_zeroed()
382 }
383 }
384}
385
386impl From<VersionResponse2> for VersionResponse3 {
387 fn from(value: VersionResponse2) -> Self {
388 Self {
389 version_response2: value,
390 ..FromZeros::new_zeroed()
391 }
392 }
393}
394
395impl From<VersionResponse> for VersionResponse3 {
396 fn from(value: VersionResponse) -> Self {
397 let version_response: VersionResponse2 = value.into();
398 version_response.into()
399 }
400}
401
402#[derive(
404 Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout, Protobuf, Inspect,
405)]
406#[repr(C, align(4))]
407#[mesh(transparent)]
408#[inspect(transparent)]
409pub struct UserDefinedData([u8; 120]);
410
411impl UserDefinedData {
412 pub fn as_pipe_params(&self) -> &PipeUserDefinedParameters {
413 PipeUserDefinedParameters::ref_from_bytes(
414 &self.0[0..size_of::<PipeUserDefinedParameters>()],
415 )
416 .expect("from bytes should not fail")
417 }
418
419 pub fn as_pipe_params_mut(&mut self) -> &mut PipeUserDefinedParameters {
420 PipeUserDefinedParameters::mut_from_bytes(
421 &mut self.0[0..size_of::<PipeUserDefinedParameters>()],
422 )
423 .expect("from bytes should not fail")
424 }
425
426 pub fn as_hvsock_params(&self) -> &HvsockUserDefinedParameters {
427 HvsockUserDefinedParameters::ref_from_bytes(
428 &self.0[0..size_of::<HvsockUserDefinedParameters>()],
429 )
430 .expect("from bytes should not fail")
431 }
432
433 pub fn as_hvsock_params_mut(&mut self) -> &mut HvsockUserDefinedParameters {
434 HvsockUserDefinedParameters::mut_from_bytes(
435 &mut self.0[0..size_of::<HvsockUserDefinedParameters>()],
436 )
437 .expect("from bytes should not fail")
438 }
439}
440
441impl Deref for UserDefinedData {
442 type Target = [u8; 120];
443
444 fn deref(&self) -> &Self::Target {
445 &self.0
446 }
447}
448
449impl DerefMut for UserDefinedData {
450 fn deref_mut(&mut self) -> &mut Self::Target {
451 &mut self.0
452 }
453}
454
455impl From<[u8; 120]> for UserDefinedData {
456 fn from(value: [u8; 120]) -> Self {
457 Self(value)
458 }
459}
460
461impl From<UserDefinedData> for [u8; 120] {
462 fn from(value: UserDefinedData) -> Self {
463 value.0
464 }
465}
466
467impl Default for UserDefinedData {
468 fn default() -> Self {
469 Self::new_zeroed()
470 }
471}
472
473impl std::fmt::Debug for UserDefinedData {
474 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
475 if self.0.iter().all(|&b| b == 0) {
476 write!(f, "UserDefinedData([<all-zeroes>])")
478 } else {
479 write!(f, "UserDefinedData([")?;
481 for byte in &self.0 {
482 write!(f, "{:02X}", byte)?;
483 }
484 write!(f, "])")
485 }
486 }
487}
488
489#[repr(C)]
490#[derive(
491 Copy, Clone, Debug, Inspect, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout,
492)]
493#[inspect(extra = "Self::inspect_extra")]
494pub struct OfferChannel {
495 pub interface_id: Guid,
496 pub instance_id: Guid,
497 #[inspect(skip)]
498 pub rsvd: [u32; 4],
499 pub flags: OfferFlags,
500 pub mmio_megabytes: u16,
501 pub user_defined: UserDefinedData,
502 pub subchannel_index: u16,
503 pub mmio_megabytes_optional: u16,
504 pub channel_id: ChannelId,
505 pub monitor_id: u8,
506 pub monitor_allocated: u8,
507 pub is_dedicated: u16,
508 pub connection_id: u32,
509}
510
511impl OfferChannel {
512 fn inspect_extra(&self, resp: &mut inspect::Response<'_>) {
513 const SHUTDOWN_IC: Guid = guid::guid!("0e0b6031-5213-4934-818b-38d90ced39db");
521 const KVP_IC: Guid = guid::guid!("a9a0f4e7-5a45-4d96-b827-8a841e8c03e6");
522 const VSS_IC: Guid = guid::guid!("35fa2e29-ea23-4236-96ae-3a6ebacba440");
523 const TIMESYNC_IC: Guid = guid::guid!("9527e630-d0ae-497b-adce-e80ab0175caf");
524 const HEARTBEAT_IC: Guid = guid::guid!("57164f39-9115-4e78-ab55-382f3bd5422d");
525 const RDV_IC: Guid = guid::guid!("276aacf4-ac15-426c-98dd-7521ad3f01fe");
526
527 const INHERITED_ACTIVATION: Guid = guid::guid!("3375baf4-9e15-4b30-b765-67acb10d607b");
528
529 const NET: Guid = guid::guid!("f8615163-df3e-46c5-913f-f2d2f965ed0e");
530 const SCSI: Guid = guid::guid!("ba6163d9-04a1-4d29-b605-72e2ffb1dc7f");
531 const VPCI: Guid = guid::guid!("44c4f61d-4444-4400-9d52-802e27ede19f");
532
533 resp.field_with("interface_name", || match self.interface_id {
534 SHUTDOWN_IC => "shutdown_ic",
535 KVP_IC => "kvp_ic",
536 VSS_IC => "vss_ic",
537 TIMESYNC_IC => "timesync_ic",
538 HEARTBEAT_IC => "heartbeat_ic",
539 RDV_IC => "rdv_ic",
540 INHERITED_ACTIVATION => "inherited_activation",
541 NET => "net",
542 SCSI => "scsi",
543 VPCI => "vpci",
544 _ => "unknown",
545 });
546 }
547}
548
549#[derive(Inspect)]
550#[bitfield(u16)]
551#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq, Protobuf)]
552#[mesh(transparent)]
553pub struct OfferFlags {
554 pub enumerate_device_interface: bool, pub confidential_ring_buffer: bool, pub confidential_external_memory: bool, pub require_pinned_external_memory: bool, pub named_pipe_mode: bool, #[bits(8)]
564 _reserved2: u16,
565 pub tlnpi_provider: bool, #[bits(2)]
567 _reserved3: u16,
568}
569
570open_enum! {
571 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
573 pub enum PipeType: u32 {
574 BYTE = 0,
575 MESSAGE = 4,
576 }
577}
578
579#[derive(
581 Copy,
582 Clone,
583 Debug,
584 PartialEq,
585 Eq,
586 IntoBytes,
587 FromBytes,
588 Immutable,
589 KnownLayout,
590 Protobuf,
591 Inspect,
592)]
593#[repr(transparent)]
594#[mesh(transparent)]
595#[inspect(transparent)]
596pub struct PipeUserDefinedData([u8; 112]);
597
598impl From<[u8; 112]> for PipeUserDefinedData {
599 fn from(value: [u8; 112]) -> Self {
600 Self(value)
601 }
602}
603
604impl From<PipeUserDefinedData> for [u8; 112] {
605 fn from(value: PipeUserDefinedData) -> Self {
606 value.0
607 }
608}
609
610impl Default for PipeUserDefinedData {
611 fn default() -> Self {
612 Self::new_zeroed()
613 }
614}
615
616#[repr(C)]
618#[derive(Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
619pub struct PipeUserDefinedParameters {
620 pub pipe_type: PipeType,
621 pub user_defined: PipeUserDefinedData,
622 pub flags: PipeFlags,
623}
624
625static_assertions::const_assert_eq!(
626 size_of::<PipeUserDefinedParameters>(),
627 size_of::<UserDefinedData>()
628);
629
630#[derive(Inspect)]
632#[bitfield(u32)]
633#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq, Protobuf)]
634#[mesh(transparent)]
635pub struct PipeFlags {
636 pub gpa_direct: bool,
638 #[bits(31)]
639 _reserved: u32,
640}
641
642#[repr(C)]
643#[derive(Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
644pub struct HvsockUserDefinedParameters {
645 pub pipe_type: PipeType,
646 pub is_for_guest_accept: u8,
647 pub is_for_guest_container: u8,
648 pub version: Unalign<HvsockParametersVersion>, pub silo_id: Unalign<Guid>, pub _padding: [u8; 2],
651}
652
653impl HvsockUserDefinedParameters {
654 pub fn new(is_for_guest_accept: bool, is_for_guest_container: bool, silo_id: Guid) -> Self {
655 Self {
656 pipe_type: PipeType::BYTE,
657 is_for_guest_accept: is_for_guest_accept.into(),
658 is_for_guest_container: is_for_guest_container.into(),
659 version: Unalign::new(HvsockParametersVersion::RS5),
660 silo_id: Unalign::new(silo_id),
661 _padding: [0; 2],
662 }
663 }
664}
665
666open_enum! {
667 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
669 pub enum HvsockParametersVersion: u32 {
670 PRE_RS5 = 0,
671 RS5 = 1,
672 }
673}
674
675#[repr(C)]
676#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)]
677pub struct RescindChannelOffer {
678 pub channel_id: ChannelId,
679}
680
681#[repr(C)]
682#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
683pub struct GpadlHeader {
684 pub channel_id: ChannelId,
685 pub gpadl_id: GpadlId,
686 pub len: u16,
687 pub count: u16,
688}
689
690impl GpadlHeader {
691 pub const MAX_DATA_VALUES: usize = (MAX_MESSAGE_SIZE - Self::MESSAGE_SIZE) / size_of::<u64>();
693}
694
695#[repr(C)]
696#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
697pub struct GpadlBody {
698 pub rsvd: u32,
699 pub gpadl_id: GpadlId,
700}
701
702impl GpadlBody {
703 pub const MAX_DATA_VALUES: usize = (MAX_MESSAGE_SIZE - Self::MESSAGE_SIZE) / size_of::<u64>();
705}
706
707#[repr(C)]
708#[derive(Copy, Clone, Eq, PartialEq, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
709pub struct GpadlCreated {
710 pub channel_id: ChannelId,
711 pub gpadl_id: GpadlId,
712 pub status: i32,
713}
714
715pub const VP_INDEX_DISABLE_INTERRUPT: u32 = u32::MAX;
717
718pub fn vp_index_if_enabled(vp_index: u32) -> Option<u32> {
720 (vp_index != VP_INDEX_DISABLE_INTERRUPT).then_some(vp_index)
721}
722
723#[repr(C)]
724#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
725pub struct OpenChannel {
726 pub channel_id: ChannelId,
727 pub open_id: u32,
728 pub ring_buffer_gpadl_id: GpadlId,
729 pub target_vp: u32,
730 pub downstream_ring_buffer_page_offset: u32,
731 pub user_data: UserDefinedData,
732}
733
734#[bitfield(u16)]
735#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
736pub struct OpenChannelFlags {
737 pub redirect_interrupt: bool,
740
741 #[bits(15)]
742 pub unused: u16,
743}
744
745#[repr(C)]
748#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
749pub struct OpenChannel2 {
750 pub open_channel: OpenChannel,
751
752 pub connection_id: u32,
754 pub event_flag: u16,
755
756 pub flags: OpenChannelFlags,
758}
759
760impl From<OpenChannel> for OpenChannel2 {
761 fn from(value: OpenChannel) -> Self {
762 Self {
763 open_channel: value,
764 ..FromZeros::new_zeroed()
765 }
766 }
767}
768
769#[repr(C)]
770#[derive(PartialEq, Eq, Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
771pub struct OpenResult {
772 pub channel_id: ChannelId,
773 pub open_id: u32,
774 pub status: u32,
775}
776
777#[repr(C)]
778#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
779pub struct CloseChannel {
780 pub channel_id: ChannelId,
781}
782
783#[repr(C)]
784#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
785pub struct RelIdReleased {
786 pub channel_id: ChannelId,
787}
788
789#[repr(C)]
790#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
791pub struct GpadlTeardown {
792 pub channel_id: ChannelId,
793 pub gpadl_id: GpadlId,
794}
795
796#[repr(C)]
797#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
798pub struct GpadlTorndown {
799 pub gpadl_id: GpadlId,
800}
801
802#[repr(C)]
803#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
804pub struct OpenReservedChannel {
805 pub channel_id: ChannelId,
806 pub target_vp: u32,
807 pub target_sint: u32,
808 pub ring_buffer_gpadl: GpadlId,
809 pub downstream_page_offset: u32,
810}
811
812#[repr(C)]
813#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
814pub struct CloseReservedChannel {
815 pub channel_id: ChannelId,
816 pub target_vp: u32,
817 pub target_sint: u32,
818}
819
820#[repr(C)]
821#[derive(PartialEq, Eq, Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
822pub struct CloseReservedChannelResponse {
823 pub channel_id: ChannelId,
824}
825
826#[repr(C)]
827#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
828pub struct TlConnectRequest {
829 pub endpoint_id: Guid,
830 pub service_id: Guid,
831}
832
833#[repr(C)]
834#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
835pub struct TlConnectRequest2 {
836 pub base: TlConnectRequest,
837 pub silo_id: Guid,
838}
839
840impl From<TlConnectRequest> for TlConnectRequest2 {
841 fn from(value: TlConnectRequest) -> Self {
842 Self {
843 base: value,
844 ..FromZeros::new_zeroed()
845 }
846 }
847}
848
849#[repr(C)]
850#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
851pub struct TlConnectResult {
852 pub endpoint_id: Guid,
853 pub service_id: Guid,
854 pub status: i32,
855}
856
857#[repr(C)]
858#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
859pub struct ModifyChannel {
860 pub channel_id: ChannelId,
861 pub target_vp: u32,
862}
863
864#[repr(C)]
865#[derive(PartialEq, Eq, Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
866pub struct ModifyChannelResponse {
867 pub channel_id: ChannelId,
868 pub status: i32,
869}
870
871#[repr(C)]
872#[derive(PartialEq, Eq, Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
873pub struct ModifyConnection {
874 pub parent_to_child_monitor_page_gpa: u64,
875 pub child_to_parent_monitor_page_gpa: u64,
876}
877
878#[repr(C)]
879#[derive(PartialEq, Eq, Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
880pub struct ModifyConnectionResponse {
881 pub connection_state: ConnectionState,
882}
883
884#[repr(C)]
888#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
889pub struct RequestOffers {}
890
891#[repr(C)]
892#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
893pub struct Unload {}
894
895#[repr(C)]
896#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
897pub struct UnloadComplete {}
898
899#[repr(C)]
900#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
901pub struct AllOffersDelivered {}
902
903#[repr(C)]
904#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
905pub struct Pause;
906
907#[repr(C)]
908#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
909pub struct PauseResponse;
910
911#[repr(C)]
912#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)]
913pub struct Resume;