1mod packet;
4mod response;
5
6use vmi_core::{VmiContext, VmiDriver, VmiOs};
7
8pub use self::{packet::BridgePacket, response::BridgeResponse};
9
10pub trait BridgeDispatch<Driver, Os, T = ()>
12where
13 Driver: VmiDriver,
14 Os: VmiOs<Driver>,
15{
16 fn dispatch(
18 &mut self,
19 vmi: &VmiContext<'_, Driver, Os>,
20 packet: BridgePacket,
21 ) -> Option<BridgeResponse<T>>;
22}
23
24pub trait BridgeHandler<Driver, Os, T = ()>: BridgeDispatch<Driver, Os, T>
26where
27 Driver: VmiDriver,
28 Os: VmiOs<Driver>,
29{
30 const EMPTY: bool = false;
34
35 const MAGIC: u32;
37
38 const REQUEST: u16;
40
41 const VERIFY_VALUE1: Option<u64> = None;
47
48 const VERIFY_VALUE2: Option<u64> = None;
54
55 const VERIFY_VALUE3: Option<u64> = None;
61
62 const VERIFY_VALUE4: Option<u64> = None;
68}
69
70macro_rules! impl_bridge_dispatch {
71 ($($ty:ident),*) => {
72 #[allow(non_snake_case)]
73 impl<Driver, Os, T, $($ty),*> BridgeDispatch<Driver, Os, T> for ($($ty),+,)
74 where
75 Driver: VmiDriver,
76 Os: VmiOs<Driver>,
77 $($ty: BridgeHandler<Driver, Os, T>,)+
78 {
79 fn dispatch(&mut self, vmi: &VmiContext<'_, Driver, Os>, packet: BridgePacket) -> Option<BridgeResponse<T>> {
80 let ($($ty,)+) = self;
81
82 $(
83 if packet.request() == <$ty as BridgeHandler<Driver, Os, T>>::REQUEST {
84 return $ty.dispatch(vmi, packet);
85 }
86 )*
87
88 None
89 }
90 }
91 };
92}
93
94impl<Driver, Os, T> BridgeDispatch<Driver, Os, T> for ()
95where
96 Driver: VmiDriver,
97 Os: VmiOs<Driver>,
98{
99 fn dispatch(
100 &mut self,
101 _vmi: &VmiContext<'_, Driver, Os>,
102 _packet: BridgePacket,
103 ) -> Option<BridgeResponse<T>> {
104 None
105 }
106}
107
108impl<Driver, Os, T> BridgeHandler<Driver, Os, T> for ()
109where
110 Driver: VmiDriver,
111 Os: VmiOs<Driver>,
112{
113 const EMPTY: bool = true;
114 const MAGIC: u32 = 0;
115 const REQUEST: u16 = 0;
116}
117
118impl_bridge_dispatch!(B1);
119impl_bridge_dispatch!(B1, B2);
120impl_bridge_dispatch!(B1, B2, B3);
121impl_bridge_dispatch!(B1, B2, B3, B4);
122impl_bridge_dispatch!(B1, B2, B3, B4, B5);
123impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6);
124impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7);
125impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8);
126impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9);
127impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10);
128impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11);
129impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12);
130impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13);
131impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14);
132impl_bridge_dispatch!(
133 B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15
134);
135impl_bridge_dispatch!(
136 B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16
137);
138
139pub struct Bridge<Driver, Os, B, T = ()>
141where
142 Driver: VmiDriver,
143 Os: VmiOs<Driver>,
144 B: BridgeDispatch<Driver, Os, T>,
145{
146 handlers: B,
147 _phantom: std::marker::PhantomData<(Driver, Os, T)>,
148}
149
150impl<Driver, Os, B, T> Bridge<Driver, Os, B, T>
151where
152 Driver: VmiDriver,
153 Os: VmiOs<Driver>,
154 B: BridgeDispatch<Driver, Os, T>,
155{
156 pub fn new(handlers: B) -> Self {
158 Self {
159 handlers,
160 _phantom: std::marker::PhantomData,
161 }
162 }
163}
164
165impl<Driver, Os, B, T> BridgeDispatch<Driver, Os, T> for Bridge<Driver, Os, B, T>
166where
167 Driver: VmiDriver,
168 Os: VmiOs<Driver>,
169 B: BridgeDispatch<Driver, Os, T>,
170{
171 fn dispatch(
172 &mut self,
173 vmi: &VmiContext<'_, Driver, Os>,
174 packet: BridgePacket,
175 ) -> Option<BridgeResponse<T>> {
176 self.handlers.dispatch(vmi, packet)
177 }
178}