Skip to main content

fastboop_schema/
bin.rs

1use alloc::collections::BTreeMap;
2use alloc::string::String;
3use alloc::vec::Vec;
4
5use gibblox_pipeline::bin::PipelineSourceBin;
6
7use serde::{Deserialize, Serialize};
8
9use crate::{
10    Boot, BootProfile, BootProfileArtifactPathSource, BootProfileArtifactSource, BootProfileDevice,
11    BootProfileDeviceStage0, BootProfileRootfs, BootProfileRootfsErofsSource,
12    BootProfileRootfsExt4Source, BootProfileRootfsFatSource, BootProfileRootfsFilesystemSource,
13    BootProfileRootfsOstreeSource, BootProfileStage0, DeviceProfile, ExistsFlag, FastbootGetvarEq,
14    FastbootGetvarExists, FastbootGetvarNotEq, FastbootGetvarNotExists, FastbootGetvarStartsWith,
15    InjectMac, MatchRule, NotExistsFlag, ProbeStep,
16};
17
18// v0 wire formats are intentionally unstable while fastboop is unreleased.
19pub const BOOT_PROFILE_BIN_FORMAT_V0: u16 = 0;
20pub const BOOT_PROFILE_BIN_V0_MAGIC: [u8; 8] = *b"FBOOPROF";
21pub const BOOT_PROFILE_BIN_V0_HEADER_LEN: usize = 10;
22
23// v0 wire formats are intentionally unstable while fastboop is unreleased.
24pub const DEV_PROFILE_BIN_FORMAT_V0: u16 = 0;
25pub const DEV_PROFILE_BIN_V0_MAGIC: [u8; 8] = *b"FBOODEVP";
26pub const DEV_PROFILE_BIN_V0_HEADER_LEN: usize = 10;
27
28#[derive(Clone, Debug, Deserialize, Serialize)]
29pub struct BootProfileBin {
30    pub id: String,
31    pub display_name: Option<String>,
32    pub rootfs: BootProfileRootfsBin,
33    pub kernel: Option<BootProfileArtifactPathSourceBin>,
34    pub dtbs: Option<BootProfileArtifactPathSourceBin>,
35    pub dt_overlays: Vec<Vec<u8>>,
36    pub extra_cmdline: Option<String>,
37    pub stage0: BootProfileStage0Bin,
38}
39
40#[derive(Clone, Debug, Deserialize, Serialize)]
41pub struct BootProfileArtifactPathSourceBin {
42    pub path: String,
43    pub source: BootProfileRootfsBin,
44}
45
46#[derive(Clone, Debug, Deserialize, Serialize)]
47pub enum BootProfileRootfsBin {
48    Ostree {
49        source: BootProfileRootfsFilesystemBin,
50    },
51    Erofs {
52        source: PipelineSourceBin,
53    },
54    Ext4 {
55        source: PipelineSourceBin,
56    },
57    Fat {
58        source: PipelineSourceBin,
59    },
60}
61
62#[derive(Clone, Debug, Deserialize, Serialize)]
63pub enum BootProfileRootfsFilesystemBin {
64    Erofs { source: PipelineSourceBin },
65    Ext4 { source: PipelineSourceBin },
66    Fat { source: PipelineSourceBin },
67}
68
69#[derive(Clone, Debug, Deserialize, Serialize)]
70pub struct BootProfileStage0Bin {
71    pub kernel_modules: Vec<String>,
72    pub devices: BTreeMap<String, BootProfileDeviceBin>,
73}
74
75#[derive(Clone, Debug, Deserialize, Serialize)]
76pub struct BootProfileDeviceBin {
77    pub dt_overlays: Vec<Vec<u8>>,
78    pub extra_cmdline: Option<String>,
79    pub stage0: BootProfileDeviceStage0Bin,
80}
81
82#[derive(Clone, Debug, Deserialize, Serialize)]
83pub struct BootProfileDeviceStage0Bin {
84    pub kernel_modules: Vec<String>,
85    pub inject_mac: Option<InjectMacBin>,
86}
87
88#[derive(Clone, Debug, Deserialize, Serialize)]
89pub struct DeviceProfileBin {
90    pub id: String,
91    pub display_name: Option<String>,
92    pub devicetree_name: String,
93    pub r#match: Vec<MatchRule>,
94    pub probe: Vec<ProbeStepBin>,
95    pub boot: Boot,
96}
97
98#[derive(Clone, Debug, Deserialize, Serialize)]
99pub enum ProbeStepBin {
100    FastbootGetvarEq { name: String, equals: String },
101    FastbootGetvarStartsWith { name: String, starts_with: String },
102    FastbootGetvarNotEq { name: String, not_equals: String },
103    FastbootGetvarExists { name: String },
104    FastbootGetvarNotExists { name: String },
105}
106
107#[derive(Clone, Debug, Deserialize, Serialize)]
108pub struct InjectMacBin {
109    pub wifi: Option<String>,
110    pub bluetooth: Option<String>,
111}
112
113impl From<DeviceProfile> for DeviceProfileBin {
114    fn from(profile: DeviceProfile) -> Self {
115        Self {
116            id: profile.id,
117            display_name: profile.display_name,
118            devicetree_name: profile.devicetree_name,
119            r#match: profile.r#match,
120            probe: profile.probe.into_iter().map(ProbeStepBin::from).collect(),
121            boot: profile.boot,
122        }
123    }
124}
125
126impl From<DeviceProfileBin> for DeviceProfile {
127    fn from(profile: DeviceProfileBin) -> Self {
128        Self {
129            id: profile.id,
130            display_name: profile.display_name,
131            devicetree_name: profile.devicetree_name,
132            r#match: profile.r#match,
133            probe: profile.probe.into_iter().map(ProbeStep::from).collect(),
134            boot: profile.boot,
135        }
136    }
137}
138
139impl From<ProbeStep> for ProbeStepBin {
140    fn from(step: ProbeStep) -> Self {
141        match step {
142            ProbeStep::FastbootGetvarEq(FastbootGetvarEq { name, equals }) => {
143                ProbeStepBin::FastbootGetvarEq { name, equals }
144            }
145            ProbeStep::FastbootGetvarStartsWith(FastbootGetvarStartsWith { name, starts_with }) => {
146                ProbeStepBin::FastbootGetvarStartsWith { name, starts_with }
147            }
148            ProbeStep::FastbootGetvarNotEq(FastbootGetvarNotEq { name, not_equals }) => {
149                ProbeStepBin::FastbootGetvarNotEq { name, not_equals }
150            }
151            ProbeStep::FastbootGetvarExists(FastbootGetvarExists { name, .. }) => {
152                ProbeStepBin::FastbootGetvarExists { name }
153            }
154            ProbeStep::FastbootGetvarNotExists(FastbootGetvarNotExists { name, .. }) => {
155                ProbeStepBin::FastbootGetvarNotExists { name }
156            }
157        }
158    }
159}
160
161impl From<ProbeStepBin> for ProbeStep {
162    fn from(step: ProbeStepBin) -> Self {
163        match step {
164            ProbeStepBin::FastbootGetvarEq { name, equals } => {
165                ProbeStep::FastbootGetvarEq(FastbootGetvarEq { name, equals })
166            }
167            ProbeStepBin::FastbootGetvarStartsWith { name, starts_with } => {
168                ProbeStep::FastbootGetvarStartsWith(FastbootGetvarStartsWith { name, starts_with })
169            }
170            ProbeStepBin::FastbootGetvarNotEq { name, not_equals } => {
171                ProbeStep::FastbootGetvarNotEq(FastbootGetvarNotEq { name, not_equals })
172            }
173            ProbeStepBin::FastbootGetvarExists { name } => {
174                ProbeStep::FastbootGetvarExists(FastbootGetvarExists {
175                    name,
176                    exists: Some(ExistsFlag),
177                })
178            }
179            ProbeStepBin::FastbootGetvarNotExists { name } => {
180                ProbeStep::FastbootGetvarNotExists(FastbootGetvarNotExists {
181                    name,
182                    not_exists: Some(NotExistsFlag),
183                })
184            }
185        }
186    }
187}
188
189impl From<InjectMac> for InjectMacBin {
190    fn from(mac: InjectMac) -> Self {
191        Self {
192            wifi: mac.wifi,
193            bluetooth: mac.bluetooth,
194        }
195    }
196}
197
198impl From<InjectMacBin> for InjectMac {
199    fn from(mac: InjectMacBin) -> Self {
200        Self {
201            wifi: mac.wifi,
202            bluetooth: mac.bluetooth,
203        }
204    }
205}
206
207impl From<BootProfile> for BootProfileBin {
208    fn from(profile: BootProfile) -> Self {
209        Self {
210            id: profile.id,
211            display_name: profile.display_name,
212            rootfs: BootProfileRootfsBin::from(profile.rootfs),
213            kernel: profile.kernel.map(BootProfileArtifactPathSourceBin::from),
214            dtbs: profile.dtbs.map(BootProfileArtifactPathSourceBin::from),
215            dt_overlays: profile.dt_overlays,
216            extra_cmdline: profile.extra_cmdline,
217            stage0: BootProfileStage0Bin::from(profile.stage0),
218        }
219    }
220}
221
222impl From<BootProfileBin> for BootProfile {
223    fn from(profile: BootProfileBin) -> Self {
224        Self {
225            id: profile.id,
226            display_name: profile.display_name,
227            rootfs: BootProfileRootfs::from(profile.rootfs),
228            kernel: profile.kernel.map(BootProfileArtifactPathSource::from),
229            dtbs: profile.dtbs.map(BootProfileArtifactPathSource::from),
230            dt_overlays: profile.dt_overlays,
231            extra_cmdline: profile.extra_cmdline,
232            stage0: BootProfileStage0::from(profile.stage0),
233        }
234    }
235}
236
237impl From<BootProfileArtifactPathSource> for BootProfileArtifactPathSourceBin {
238    fn from(source: BootProfileArtifactPathSource) -> Self {
239        Self {
240            path: source.path,
241            source: BootProfileRootfsBin::from(source.source),
242        }
243    }
244}
245
246impl From<BootProfileArtifactPathSourceBin> for BootProfileArtifactPathSource {
247    fn from(source: BootProfileArtifactPathSourceBin) -> Self {
248        Self {
249            path: source.path,
250            source: BootProfileRootfs::from(source.source),
251        }
252    }
253}
254
255impl From<BootProfileRootfs> for BootProfileRootfsBin {
256    fn from(rootfs: BootProfileRootfs) -> Self {
257        match rootfs {
258            BootProfileRootfs::Ostree(BootProfileRootfsOstreeSource { ostree }) => Self::Ostree {
259                source: BootProfileRootfsFilesystemBin::from(ostree),
260            },
261            BootProfileRootfs::Erofs(BootProfileRootfsErofsSource { erofs }) => Self::Erofs {
262                source: PipelineSourceBin::from(erofs),
263            },
264            BootProfileRootfs::Ext4(BootProfileRootfsExt4Source { ext4 }) => Self::Ext4 {
265                source: PipelineSourceBin::from(ext4),
266            },
267            BootProfileRootfs::Fat(BootProfileRootfsFatSource { fat }) => Self::Fat {
268                source: PipelineSourceBin::from(fat),
269            },
270        }
271    }
272}
273
274impl From<BootProfileRootfsBin> for BootProfileRootfs {
275    fn from(rootfs: BootProfileRootfsBin) -> Self {
276        match rootfs {
277            BootProfileRootfsBin::Ostree { source } => {
278                Self::Ostree(BootProfileRootfsOstreeSource {
279                    ostree: BootProfileRootfsFilesystemSource::from(source),
280                })
281            }
282            BootProfileRootfsBin::Erofs { source } => Self::Erofs(BootProfileRootfsErofsSource {
283                erofs: BootProfileArtifactSource::from(source),
284            }),
285            BootProfileRootfsBin::Ext4 { source } => Self::Ext4(BootProfileRootfsExt4Source {
286                ext4: BootProfileArtifactSource::from(source),
287            }),
288            BootProfileRootfsBin::Fat { source } => Self::Fat(BootProfileRootfsFatSource {
289                fat: BootProfileArtifactSource::from(source),
290            }),
291        }
292    }
293}
294
295impl From<BootProfileRootfsFilesystemSource> for BootProfileRootfsFilesystemBin {
296    fn from(source: BootProfileRootfsFilesystemSource) -> Self {
297        match source {
298            BootProfileRootfsFilesystemSource::Erofs(BootProfileRootfsErofsSource { erofs }) => {
299                Self::Erofs {
300                    source: PipelineSourceBin::from(erofs),
301                }
302            }
303            BootProfileRootfsFilesystemSource::Ext4(BootProfileRootfsExt4Source { ext4 }) => {
304                Self::Ext4 {
305                    source: PipelineSourceBin::from(ext4),
306                }
307            }
308            BootProfileRootfsFilesystemSource::Fat(BootProfileRootfsFatSource { fat }) => {
309                Self::Fat {
310                    source: PipelineSourceBin::from(fat),
311                }
312            }
313        }
314    }
315}
316
317impl From<BootProfileRootfsFilesystemBin> for BootProfileRootfsFilesystemSource {
318    fn from(source: BootProfileRootfsFilesystemBin) -> Self {
319        match source {
320            BootProfileRootfsFilesystemBin::Erofs { source } => {
321                Self::Erofs(BootProfileRootfsErofsSource {
322                    erofs: BootProfileArtifactSource::from(source),
323                })
324            }
325            BootProfileRootfsFilesystemBin::Ext4 { source } => {
326                Self::Ext4(BootProfileRootfsExt4Source {
327                    ext4: BootProfileArtifactSource::from(source),
328                })
329            }
330            BootProfileRootfsFilesystemBin::Fat { source } => {
331                Self::Fat(BootProfileRootfsFatSource {
332                    fat: BootProfileArtifactSource::from(source),
333                })
334            }
335        }
336    }
337}
338
339impl From<BootProfileStage0> for BootProfileStage0Bin {
340    fn from(stage0: BootProfileStage0) -> Self {
341        Self {
342            kernel_modules: stage0.kernel_modules,
343            devices: stage0
344                .devices
345                .into_iter()
346                .map(|(device_id, device)| (device_id, BootProfileDeviceBin::from(device)))
347                .collect(),
348        }
349    }
350}
351
352impl From<BootProfileStage0Bin> for BootProfileStage0 {
353    fn from(stage0: BootProfileStage0Bin) -> Self {
354        Self {
355            kernel_modules: stage0.kernel_modules,
356            devices: stage0
357                .devices
358                .into_iter()
359                .map(|(device_id, device)| (device_id, BootProfileDevice::from(device)))
360                .collect(),
361        }
362    }
363}
364
365impl From<BootProfileDevice> for BootProfileDeviceBin {
366    fn from(device: BootProfileDevice) -> Self {
367        Self {
368            dt_overlays: device.dt_overlays,
369            extra_cmdline: device.extra_cmdline,
370            stage0: BootProfileDeviceStage0Bin::from(device.stage0),
371        }
372    }
373}
374
375impl From<BootProfileDeviceBin> for BootProfileDevice {
376    fn from(device: BootProfileDeviceBin) -> Self {
377        Self {
378            dt_overlays: device.dt_overlays,
379            extra_cmdline: device.extra_cmdline,
380            stage0: BootProfileDeviceStage0::from(device.stage0),
381        }
382    }
383}
384
385impl From<BootProfileDeviceStage0> for BootProfileDeviceStage0Bin {
386    fn from(stage0: BootProfileDeviceStage0) -> Self {
387        Self {
388            kernel_modules: stage0.kernel_modules,
389            inject_mac: stage0.inject_mac.map(InjectMacBin::from),
390        }
391    }
392}
393
394impl From<BootProfileDeviceStage0Bin> for BootProfileDeviceStage0 {
395    fn from(stage0: BootProfileDeviceStage0Bin) -> Self {
396        Self {
397            kernel_modules: stage0.kernel_modules,
398            inject_mac: stage0.inject_mac.map(InjectMac::from),
399        }
400    }
401}