-
Notifications
You must be signed in to change notification settings - Fork 37
/
manifest.rs
106 lines (89 loc) · 2.45 KB
/
manifest.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//! Flipper Zero Manifest.
use core::ffi::c_char;
use flipperzero_sys as sys;
const MANIFEST_MAGIC: u32 = 0x52474448;
const HARDWARE_TARGET: u16 = 7;
const DEFAULT_STACK_SIZE: u16 = 2048; // 2 KiB
#[macro_export]
macro_rules! manifest {
($($field:ident = $value:expr),*) => {
#[no_mangle]
#[link_section = ".fapmeta"]
static FAP_MANIFEST: $crate::manifest::ApplicationManifestV1 = $crate::manifest::ApplicationManifestV1 {
$( $field: $crate::manifest::set::$field($value), )*
.. $crate::manifest::ApplicationManifestV1::default()
};
};
}
#[macro_export]
macro_rules! _manifest_field {
(stack_size = $value:expr) => {
stack_size: $value
};
(app_version = $value:expr) => {
app_version: $value
};
(name = $value:expr) => {
name: $crate::manifest::padded($value.as_bytes())
}
}
/// Manifest setters
pub mod set {
use super::padded;
pub const fn stack_size(n_bytes: u16) -> u16 {
n_bytes
}
pub const fn app_version(version: u32) -> u32 {
version
}
pub const fn name<const SIZE: usize>(name: &str) -> [u8; SIZE] {
padded(name.as_bytes())
}
}
#[repr(C, packed)]
pub struct ManifestBase {
pub manifest_magic: u32,
pub manifest_version: u32,
pub api_version: u32,
pub hardware_target_id: u16,
}
/// Application Manifest (version 1).
#[repr(C, packed)]
pub struct ApplicationManifestV1 {
pub base: ManifestBase,
pub stack_size: u16,
pub app_version: u32,
pub name: [u8; 32],
pub has_icon: c_char,
pub icon: [u8; 32],
}
impl ApplicationManifestV1 {
/// Default manifest.
pub const fn default() -> Self {
Self {
base: ManifestBase {
manifest_magic: MANIFEST_MAGIC,
manifest_version: 1,
api_version: sys::API_VERSION,
hardware_target_id: HARDWARE_TARGET,
},
stack_size: DEFAULT_STACK_SIZE,
app_version: 1,
name: padded(b"Application"),
has_icon: 0,
icon: [0; 32],
}
}
}
/// Pads an array with NULL bytes.
/// Ensures that there's always a NULL byte at the end.
const fn padded<const SIZE: usize>(value: &[u8]) -> [u8; SIZE] {
let mut array: [u8; SIZE] = [0; SIZE];
let mut i = 0;
while i < array.len() - 1 && i < value.len() {
array[i] = value[i];
i += 1;
}
array[i] = 0;
array
}