dji_log_parser/record/
mod.rs

1use binrw::binread;
2use serde::Serialize;
3use std::cell::RefCell;
4#[cfg(target_arch = "wasm32")]
5use tsify_next::Tsify;
6
7use crate::decoder::record_decoder;
8use crate::layout::details::ProductType;
9use crate::utils;
10use crate::Keychain;
11
12pub mod app_gps;
13pub mod app_serious_warn;
14pub mod app_tip;
15pub mod app_warn;
16pub mod camera;
17pub mod center_battery;
18pub mod component_serial;
19pub mod custom;
20pub mod deform;
21pub mod firmware;
22pub mod gimbal;
23pub mod home;
24pub mod key_storage;
25pub mod mc_param;
26pub mod ofdm;
27pub mod osd;
28pub mod rc;
29pub mod rc_display_field;
30pub mod rc_gps;
31pub mod recover;
32pub mod smart_battery;
33pub mod smart_battery_group;
34pub mod virtual_stick;
35
36use app_gps::AppGPS;
37use app_serious_warn::AppSeriousWarn;
38use app_tip::AppTip;
39use app_warn::AppWarn;
40use camera::Camera;
41use center_battery::CenterBattery;
42use component_serial::ComponentSerial;
43use custom::Custom;
44use deform::Deform;
45use firmware::Firmware;
46use gimbal::Gimbal;
47use home::Home;
48use key_storage::KeyStorage;
49use mc_param::MCParams;
50use ofdm::OFDM;
51use osd::OSD;
52use rc::RC;
53use rc_display_field::RCDisplayField;
54use rc_gps::RCGPS;
55use recover::Recover;
56use smart_battery::SmartBattery;
57use smart_battery_group::*;
58use virtual_stick::VirtualStick;
59
60const END_BYTE: u8 = 0xFF;
61
62/// Represents the different types of records.
63///
64/// Each variant of this enum corresponds to a specific type of record in the log file.
65/// Records typically consist of a 'magic' byte indicating the record type, followed by the length of the record,
66/// the actual data, and then a terminating byte of value `0xff`.
67///
68#[binread]
69#[derive(Serialize, Debug)]
70#[serde(tag = "type", content = "content")]
71#[br(little, import { version: u8, keychain: &RefCell<Keychain>, product_type: ProductType = ProductType::None })]
72#[cfg_attr(target_arch = "wasm32", derive(Tsify))]
73pub enum Record {
74    #[br(magic = 1u8)]
75    OSD(
76        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
77        #[br(
78            pad_size_to = self_0,
79            map_stream = |reader| record_decoder(reader, 1, version, keychain, self_0),
80            args { version }
81        )]
82        OSD,
83        #[br(temp, assert(self_2 == END_BYTE))] u8,
84    ),
85    #[br(magic = 2u8)]
86    Home(
87        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
88        #[br(
89            pad_size_to = self_0,
90            map_stream = |reader| record_decoder(reader, 2, version, keychain, self_0),
91            args { version }
92        )]
93        Home,
94        #[br(temp, assert(self_2 == END_BYTE))] u8,
95    ),
96    #[br(magic = 3u8)]
97    Gimbal(
98        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
99        #[br(
100            pad_size_to = self_0,
101            map_stream = |reader| record_decoder(reader, 3, version, keychain, self_0),
102            args { version }
103        )]
104        Gimbal,
105        #[br(temp, assert(self_2 == END_BYTE))] u8,
106    ),
107    #[br(magic = 4u8)]
108    RC(
109        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
110        #[br(
111            pad_size_to = self_0,
112            map_stream = |reader| record_decoder(reader, 4, version, keychain, self_0),
113            args { product_type, version }
114        )]
115        RC,
116        #[br(temp, assert(self_2 == END_BYTE))] u8,
117    ),
118    #[br(magic = 5u8)]
119    Custom(
120        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
121        #[br(
122            pad_size_to = self_0,
123            map_stream = |reader| record_decoder(reader, 5, version, keychain, self_0)
124        )]
125        Custom,
126        #[br(temp, assert(self_2 == END_BYTE))] u8,
127    ),
128    #[br(magic = 6u8)]
129    Deform(
130        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
131        #[br(
132            pad_size_to = self_0,
133            map_stream = |reader| record_decoder(reader, 6, version, keychain, self_0)
134        )]
135        Deform,
136        #[br(temp, assert(self_2 == END_BYTE))] u8,
137    ),
138    #[br(magic = 7u8)]
139    CenterBattery(
140        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
141        #[br(
142            pad_size_to = self_0,
143            map_stream = |reader| record_decoder(reader, 7, version, keychain, self_0),
144            args { version }
145        )]
146        CenterBattery,
147        #[br(temp, assert(self_2 == END_BYTE))] u8,
148    ),
149    #[br(magic = 8u8)]
150    SmartBattery(
151        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
152        #[br(
153            pad_size_to = self_0,
154            map_stream = |reader| record_decoder(reader, 8, version, keychain, self_0)
155        )]
156        SmartBattery,
157        #[br(temp, assert(self_2 == END_BYTE))] u8,
158    ),
159    #[br(magic = 9u8)]
160    AppTip(
161        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
162        #[br(
163            pad_size_to = self_0,
164            map_stream = |reader| record_decoder(reader, 9, version, keychain, self_0),
165            args { length: self_0 }
166        )]
167        AppTip,
168        #[br(temp, assert(self_2 == END_BYTE))] u8,
169    ),
170    #[br(magic = 10u8)]
171    AppWarn(
172        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
173        #[br(
174            pad_size_to = self_0,
175            map_stream = |reader| record_decoder(reader, 10, version, keychain, self_0),
176            args { length: self_0 }
177        )]
178        AppWarn,
179        #[br(temp, assert(self_2 == END_BYTE))] u8,
180    ),
181    #[br(magic = 11u8)]
182    RCGPS(
183        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
184        #[br(
185            pad_size_to = self_0,
186            map_stream = |reader| record_decoder(reader, 11, version, keychain, self_0)
187        )]
188        RCGPS,
189        #[br(temp, assert(self_2 == END_BYTE))] u8,
190    ),
191    #[br(magic = 13u8)]
192    Recover(
193        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
194        #[br(
195            pad_size_to = self_0,
196            map_stream = |reader| record_decoder(reader, 13, version, keychain, self_0),
197            args { version }
198        )]
199        Recover,
200        #[br(temp, assert(self_2 == END_BYTE))] u8,
201    ),
202    #[br(magic = 14u8)]
203    AppGPS(
204        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
205        #[br(
206            pad_size_to = self_0,
207            map_stream = |reader| record_decoder(reader, 14, version, keychain, self_0)
208        )]
209        AppGPS,
210        #[br(temp, assert(self_2 == END_BYTE))] u8,
211    ),
212    #[br(magic = 15u8)]
213    Firmware(
214        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
215        #[br(
216            pad_size_to = self_0,
217            map_stream = |reader| record_decoder(reader, 15, version, keychain, self_0)
218        )]
219        Firmware,
220        #[br(temp, assert(self_2 == END_BYTE))] u8,
221    ),
222    #[br(magic = 19u8)]
223    MCParams(
224        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
225        #[br(
226            pad_size_to = self_0,
227            map_stream = |reader| record_decoder(reader, 19, version, keychain, self_0)
228        )]
229        MCParams,
230        #[br(temp, assert(self_2 == END_BYTE))] u8,
231    ),
232    #[br(magic = 22u8)]
233    SmartBatteryGroup(
234        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
235        #[br(
236            pad_size_to = self_0,
237            map_stream = |reader| record_decoder(reader, 22, version, keychain, self_0)
238        )]
239        SmartBatteryGroup,
240        #[br(temp, assert(self_2 == END_BYTE))] u8,
241    ),
242    #[br(magic = 24u8)]
243    AppSeriousWarn(
244        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
245        #[br(
246            pad_size_to = self_0,
247            map_stream = |reader| record_decoder(reader, 24, version, keychain, self_0),
248            args { length: self_0 }
249        )]
250        AppSeriousWarn,
251        #[br(temp, assert(self_2 == END_BYTE))] u8,
252    ),
253    #[br(magic = 25u8)]
254    Camera(
255        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
256        #[br(
257            pad_size_to = self_0,
258            map_stream = |reader| record_decoder(reader, 25, version, keychain, self_0),
259        )]
260        Camera,
261        #[br(temp, assert(self_2 == END_BYTE))] u8,
262    ),
263    #[br(magic = 33u8)]
264    VirtualStick(
265        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
266        #[br(
267            pad_size_to = self_0,
268            map_stream = |reader| record_decoder(reader, 33, version, keychain, self_0),
269        )]
270        VirtualStick,
271        #[br(temp, assert(self_2 == END_BYTE))] u8,
272    ),
273    #[br(magic = 40u8)]
274    ComponentSerial(
275        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
276        #[br(
277            pad_size_to = self_0,
278            map_stream = |reader| record_decoder(reader, 40, version, keychain, self_0),
279        )]
280        ComponentSerial,
281        #[br(temp, assert(self_2 == END_BYTE))] u8,
282    ),
283    #[br(magic = 49u8)]
284    OFDM(
285        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
286        #[br(
287            pad_size_to = self_0,
288            map_stream = |reader| record_decoder(reader, 49, version, keychain, self_0),
289        )]
290        OFDM,
291        #[br(temp, assert(self_2 == END_BYTE))] u8,
292    ),
293    #[br(magic = 50u8)]
294    KeyStorageRecover(
295        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
296        #[br(count = self_0)] Vec<u8>,
297        #[br(temp, assert(self_2 == 0xff))] u8,
298    ),
299    #[br(magic = 56u8)]
300    KeyStorage(
301        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
302        #[br(
303            pad_size_to = self_0,
304            map_stream = |reader| record_decoder(reader, 56, version, keychain, self_0)
305        )]
306        KeyStorage,
307        #[br(temp, assert(self_2 == END_BYTE))] u8,
308    ),
309    #[br(magic = 62u8)]
310    RCDisplayField(
311        #[br(temp, args(version <= 12), parse_with = utils::read_u16)] u16,
312        #[br(
313            pad_size_to = self_0,
314            map_stream = |reader| record_decoder(reader, 62, version, keychain, self_0),
315        )]
316        RCDisplayField,
317        #[br(temp, assert(self_2 == END_BYTE))] u8,
318    ),
319    JPEG(#[br(parse_with = utils::read_jpeg)] Vec<u8>),
320    // Valid record of unknown data
321    Unknown(
322        u8, // record_type
323        #[br(temp, args(version <= 12), parse_with = utils::read_u16, assert(self_1 > 2))] u16,
324        #[br(
325            pad_size_to = self_1,
326            count = if version <= 6 {
327                self_1
328            } else {
329                self_1 - 2
330            },
331            map_stream = |reader| record_decoder(reader, self_0, version, keychain, self_1)
332        )]
333        Vec<u8>,
334        #[br(temp, assert(self_3 == END_BYTE))] u8,
335    ),
336    // Invalid data, try to seek to next record
337    Invalid(#[br(parse_with = utils::seek_to_next_record, assert(!self_0.is_empty()))] Vec<u8>),
338}