dji_log_parser/layout/
details.rs

1use binrw::binread;
2use chrono::{DateTime, Utc};
3use serde::Serialize;
4use std::io::SeekFrom;
5#[cfg(target_arch = "wasm32")]
6use tsify_next::Tsify;
7
8#[binread]
9#[derive(Debug, Serialize, Clone)]
10#[serde(rename_all = "camelCase")]
11#[br(little, import(version: u8))]
12#[cfg_attr(target_arch = "wasm32", derive(Tsify))]
13pub struct Details {
14    #[br(count=20, map = |s: Vec<u8>| String::from_utf8_lossy(&s).trim_end_matches('\0').to_string())]
15    pub sub_street: String,
16    #[br(count=20, map = |s: Vec<u8>| String::from_utf8_lossy(&s).trim_end_matches('\0').to_string())]
17    pub street: String,
18    #[br(count=20, map = |s: Vec<u8>| String::from_utf8_lossy(&s).trim_end_matches('\0').to_string())]
19    pub city: String,
20    #[br(count=20, map = |s: Vec<u8>| String::from_utf8_lossy(&s).trim_end_matches('\0').to_string())]
21    pub area: String,
22    pub is_favorite: u8,
23    pub is_new: u8,
24    pub needs_upload: u8,
25    pub record_line_count: i32,
26    pub detail_info_checksum: i32,
27    #[cfg_attr(target_arch = "wasm32", tsify(type = "string"))]
28    #[br(map = |x: i64| DateTime::from_timestamp(x / 1000, (x % 1000 * 1000000) as u32).unwrap_or_default())]
29    pub start_time: DateTime<Utc>,
30    /// degrees
31    pub longitude: f64,
32    /// degrees
33    pub latitude: f64,
34    /// meters
35    pub total_distance: f32,
36    /// seconds
37    #[br(map = |x: i32| x as f64 / 1000.0)]
38    pub total_time: f64,
39    /// meters
40    pub max_height: f32,
41    /// meters / seconds
42    pub max_horizontal_speed: f32,
43    /// meters / seconds
44    pub max_vertical_speed: f32,
45    pub capture_num: i32,
46    pub video_time: i64,
47    pub moment_pic_image_buffer_len: [i32; 4],
48    pub moment_pic_shrink_image_buffer_len: [i32; 4],
49    /// degrees
50    #[br(map = |v: [f64; 4]| v.map(|rad: f64| rad.to_degrees()) )]
51    pub moment_pic_longitude: [f64; 4],
52    /// degrees
53    #[br(map = |v: [f64; 4]| v.map(|rad: f64| rad.to_degrees()) )]
54    pub moment_pic_latitude: [f64; 4],
55    #[br(temp)]
56    _analysis_offset: i64,
57    #[br(temp)]
58    _user_api_center_id_md5: [u8; 16],
59    #[br(seek_before = if version <= 5 { SeekFrom::Start(352) } else { SeekFrom::Current(0) })]
60    pub take_off_altitude: f32,
61    #[br(
62        seek_before = if version <= 5 { SeekFrom::Start(277) } else { SeekFrom::Current(0) },
63        map = |x: u8| ProductType::from(x))
64    ]
65    pub product_type: ProductType,
66    #[br(temp)]
67    _activation_timestamp: i64,
68    #[br(
69        seek_before = if version <= 5 { SeekFrom::Start(278) } else { SeekFrom::Current(0) },
70        count = if version <= 5 { 24 } else { 32 }, map = |s: Vec<u8>| String::from_utf8_lossy(&s).trim_end_matches('\0').to_string()
71    )]
72    pub aircraft_name: String,
73    #[br(
74        seek_before = if version <= 5 { SeekFrom::Start(267) } else { SeekFrom::Current(0) },
75        count = if version <= 5 { 10 } else { 16 }, map = |s: Vec<u8>| String::from_utf8_lossy(&s).trim_end_matches('\0').to_string()
76    )]
77    pub aircraft_sn: String,
78    #[br(
79        seek_before = if version <= 5 { SeekFrom::Start(318) } else { SeekFrom::Current(0) },
80        count = if version <= 5 { 10 } else { 16 }, map = |s: Vec<u8>| String::from_utf8_lossy(&s).trim_end_matches('\0').to_string()
81    )]
82    pub camera_sn: String,
83    #[br(count = if version <= 5 { 10 } else { 16 }, map = |s: Vec<u8>| String::from_utf8_lossy(&s).trim_end_matches('\0').to_string())]
84    pub rc_sn: String,
85    #[br(count = if version <= 5 { 10 } else { 16 }, map = |s: Vec<u8>| String::from_utf8_lossy(&s).trim_end_matches('\0').to_string())]
86    pub battery_sn: String,
87    #[br(map = |x: u8| Platform::from(x))]
88    pub app_platform: Platform,
89    #[br(map = |x: [u8; 3]| format!("{}.{}.{}", x[0], x[1], x[2]))]
90    pub app_version: String,
91}
92
93#[derive(Serialize, Debug, Clone, PartialEq, Default, Copy)]
94#[cfg_attr(target_arch = "wasm32", derive(Tsify))]
95pub enum ProductType {
96    #[default]
97    None,
98    Inspire1,
99    Phantom3Standard,
100    Phantom3Advanced,
101    Phantom3Pro,
102    OSMO,
103    Matrice100,
104    Phantom4,
105    LB2,
106    Inspire1Pro,
107    A3,
108    Matrice600,
109    Phantom34K,
110    MavicPro,
111    ZenmuseXT,
112    Inspire1RAW,
113    A2,
114    Inspire2,
115    OSMOPro,
116    OSMORaw,
117    OSMOPlus,
118    Mavic,
119    OSMOMobile,
120    OrangeCV600,
121    Phantom4Pro,
122    N3FC,
123    Spark,
124    Matrice600Pro,
125    Phantom4Advanced,
126    Phantom3SE,
127    AG405,
128    Matrice200,
129    Matrice210,
130    Matrice210RTK,
131    MavicAir,
132    Mavic2,
133    Phantom4ProV2,
134    Phantom4RTK,
135    Phantom4Multispectral,
136    Mavic2Enterprise,
137    MavicMini,
138    Matrice200V2,
139    Matrice210V2,
140    Matrice210RTKV2,
141    MavicAir2,
142    Matrice300RTK,
143    FPV,
144    MavicAir2S,
145    Mini2,
146    Mavic3,
147    MiniSE,
148    Mini3Pro,
149    Mavic3Pro,
150    Mini2SE,
151    Matrice30,
152    Mavic3Enterprise,
153    Avata,
154    Mini4Pro,
155    Avata2,
156    Matrice350RTK,
157    #[serde(untagged)]
158    Unknown(u8),
159}
160
161impl From<u8> for ProductType {
162    fn from(num: u8) -> Self {
163        match num {
164            0 => ProductType::None,
165            1 => ProductType::Inspire1,
166            2 => ProductType::Phantom3Standard,
167            3 => ProductType::Phantom3Advanced,
168            4 => ProductType::Phantom3Pro,
169            5 => ProductType::OSMO,
170            6 => ProductType::Matrice100,
171            7 => ProductType::Phantom4,
172            8 => ProductType::LB2,
173            9 => ProductType::Inspire1Pro,
174            10 => ProductType::A3,
175            11 => ProductType::Matrice600,
176            12 => ProductType::Phantom34K,
177            13 => ProductType::MavicPro,
178            14 => ProductType::ZenmuseXT,
179            15 => ProductType::Inspire1RAW,
180            16 => ProductType::A2,
181            17 => ProductType::Inspire2,
182            18 => ProductType::OSMOPro,
183            19 => ProductType::OSMORaw,
184            20 => ProductType::OSMOPlus,
185            21 => ProductType::Mavic,
186            22 => ProductType::OSMOMobile,
187            23 => ProductType::OrangeCV600,
188            24 => ProductType::Phantom4Pro,
189            25 => ProductType::N3FC,
190            26 => ProductType::Spark,
191            27 => ProductType::Matrice600Pro,
192            28 => ProductType::Phantom4Advanced,
193            29 => ProductType::Phantom3SE,
194            30 => ProductType::AG405,
195            31 => ProductType::Matrice200,
196            33 => ProductType::Matrice210,
197            34 => ProductType::Matrice210RTK,
198            38 => ProductType::MavicAir,
199            42 => ProductType::Mavic2,
200            44 => ProductType::Phantom4ProV2,
201            46 => ProductType::Phantom4RTK,
202            57 => ProductType::Phantom4Multispectral,
203            58 => ProductType::Mavic2Enterprise,
204            59 => ProductType::MavicMini,
205            60 => ProductType::Matrice200V2,
206            61 => ProductType::Matrice210V2,
207            62 => ProductType::Matrice210RTKV2,
208            67 => ProductType::MavicAir2,
209            70 => ProductType::Matrice300RTK,
210            73 => ProductType::FPV,
211            75 => ProductType::MavicAir2S,
212            76 => ProductType::Mini2,
213            77 => ProductType::Mavic3,
214            96 => ProductType::MiniSE,
215            103 => ProductType::Mini3Pro,
216            111 => ProductType::Mavic3Pro,
217            113 => ProductType::Mini2SE,
218            116 => ProductType::Matrice30,
219            118 => ProductType::Mavic3Enterprise,
220            121 => ProductType::Avata,
221            126 => ProductType::Mini4Pro,
222            152 => ProductType::Avata2,
223            170 => ProductType::Matrice350RTK,
224            _ => ProductType::Unknown(num),
225        }
226    }
227}
228
229impl ProductType {
230    pub fn battery_cell_num(&self) -> u8 {
231        match self {
232            ProductType::Inspire1 => 6,
233            ProductType::Phantom3Standard => 4,
234            ProductType::Phantom3Advanced => 4,
235            ProductType::Phantom3Pro => 4,
236            ProductType::Matrice100 => 6,
237            ProductType::Phantom4 => 4,
238            ProductType::Inspire1Pro => 6,
239            ProductType::Matrice600 => 6,
240            ProductType::Phantom34K => 4,
241            ProductType::MavicPro => 3,
242            ProductType::Inspire1RAW => 6,
243            ProductType::Inspire2 => 6,
244            ProductType::Mavic => 3,
245            ProductType::Phantom4Pro => 4,
246            ProductType::Spark => 3,
247            ProductType::Matrice600Pro => 6,
248            ProductType::Phantom4Advanced => 4,
249            ProductType::Phantom3SE => 4,
250            ProductType::Matrice200 => 6,
251            ProductType::Matrice210 => 6,
252            ProductType::Matrice210RTK => 6,
253            ProductType::MavicAir => 3,
254            ProductType::Mavic2 => 4,
255            ProductType::Phantom4ProV2 => 4,
256            ProductType::Phantom4RTK => 4,
257            ProductType::Phantom4Multispectral => 4,
258            ProductType::Mavic2Enterprise => 4,
259            ProductType::MavicMini => 2,
260            ProductType::Matrice200V2 => 6,
261            ProductType::Matrice210V2 => 6,
262            ProductType::Matrice210RTKV2 => 6,
263            ProductType::MavicAir2 => 3,
264            ProductType::Matrice300RTK => 12,
265            ProductType::FPV => 6,
266            ProductType::MavicAir2S => 3,
267            ProductType::Mini2 => 2,
268            ProductType::Mavic3 => 4,
269            ProductType::MiniSE => 2,
270            ProductType::Mini3Pro => 2,
271            ProductType::Mavic3Pro => 4,
272            ProductType::Mini2SE => 2,
273            ProductType::Matrice30 => 6,
274            ProductType::Mavic3Enterprise => 4,
275            ProductType::Avata => 5,
276            ProductType::Mini4Pro => 2,
277            ProductType::Avata2 => 4,
278            ProductType::Matrice350RTK => 12,
279            _ => 4,
280        }
281    }
282
283    pub fn battery_num(&self) -> u8 {
284        match self {
285            ProductType::Inspire1 => 2,
286            ProductType::Phantom3Standard => 1,
287            ProductType::Phantom3Advanced => 1,
288            ProductType::Phantom3Pro => 1,
289            ProductType::Matrice100 => 2,
290            ProductType::Phantom4 => 1,
291            ProductType::Inspire1Pro => 2,
292            ProductType::Matrice600 => 6,
293            ProductType::Phantom34K => 1,
294            ProductType::MavicPro => 1,
295            ProductType::Inspire1RAW => 2,
296            ProductType::Inspire2 => 2,
297            ProductType::Mavic => 1,
298            ProductType::Phantom4Pro => 1,
299            ProductType::Spark => 1,
300            ProductType::Matrice600Pro => 6,
301            ProductType::Phantom4Advanced => 1,
302            ProductType::Phantom3SE => 1,
303            ProductType::Matrice200 => 2,
304            ProductType::Matrice210 => 2,
305            ProductType::Matrice210RTK => 2,
306            ProductType::MavicAir => 1,
307            ProductType::Mavic2 => 1,
308            ProductType::Phantom4ProV2 => 1,
309            ProductType::Phantom4RTK => 1,
310            ProductType::Phantom4Multispectral => 1,
311            ProductType::Mavic2Enterprise => 1,
312            ProductType::MavicMini => 1,
313            ProductType::Matrice200V2 => 2,
314            ProductType::Matrice210V2 => 2,
315            ProductType::Matrice210RTKV2 => 2,
316            ProductType::MavicAir2 => 1,
317            ProductType::Matrice300RTK => 2,
318            ProductType::FPV => 1,
319            ProductType::MavicAir2S => 1,
320            ProductType::Mini2 => 1,
321            ProductType::Mavic3 => 1,
322            ProductType::MiniSE => 1,
323            ProductType::Mini3Pro => 1,
324            ProductType::Mavic3Pro => 1,
325            ProductType::Mini2SE => 1,
326            ProductType::Matrice30 => 2,
327            ProductType::Mavic3Enterprise => 1,
328            ProductType::Avata => 1,
329            ProductType::Mini4Pro => 1,
330            ProductType::Avata2 => 1,
331            ProductType::Matrice350RTK => 2,
332            _ => 1,
333        }
334    }
335}
336
337#[derive(Serialize, Debug, Clone, PartialEq)]
338#[cfg_attr(target_arch = "wasm32", derive(Tsify))]
339pub enum Platform {
340    IOS,
341    Android,
342    DJIFly,
343    Windows,
344    Mac,
345    Linux,
346    #[serde(untagged)]
347    Unknown(u8),
348}
349
350impl From<u8> for Platform {
351    fn from(num: u8) -> Self {
352        match num {
353            1 => Platform::IOS,
354            2 => Platform::Android,
355            6 => Platform::DJIFly,
356            10 => Platform::Windows,
357            11 => Platform::Mac,
358            12 => Platform::Linux,
359            _ => Platform::Unknown(num),
360        }
361    }
362}