Skip to content

Commit b064528

Browse files
authored
refactor: Complete CLI-to-Crate Unification Phase 4 (#15)
* refactor: remove dead parse_i_frame code (Phase 4a) - Delete unused parse_i_frame function (lines 2307-2337) - Function was marked #[allow(dead_code)] and never called - I-frames already use crate's parse_frame_data directly Part of issue #13: CLI-to-Crate Unification Phase 4 * refactor: use crate's parse_h_frame (Phase 4b) - Import parse_h_frame from bbl_parser::parser - Delete duplicate parse_h_frame function (38 lines) - Verified: MD5 checksum matches master output Part of issue #13: CLI-to-Crate Unification Phase 4 * refactor: use crate's parse_e_frame and EventFrame (Phase 4c) - Import parse_e_frame from bbl_parser::parser - Import EventFrame from bbl_parser::types - Delete duplicate parse_e_frame function (~165 lines) - Delete duplicate EventFrame struct (9 lines) - Verified: MD5 checksum matches master output Part of issue #13: CLI-to-Crate Unification Phase 4 * refactor: unify parse_s_frame with TAG2_3S32 support (Phase 4d) - Enhance crate's parse_s_frame to handle ENCODING_TAG2_3S32 - Make parse_s_frame public for CLI use - Import parse_s_frame from bbl_parser::parser in CLI - Delete duplicate parse_s_frame function (~65 lines) - Remove unused ENCODING_* constant imports from CLI - Verified: MD5 checksum matches master output Part of issue #13: CLI-to-Crate Unification Phase 4
1 parent 5c98097 commit b064528

2 files changed

Lines changed: 50 additions & 327 deletions

File tree

src/main.rs

Lines changed: 2 additions & 314 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@ use bbl_parser::conversion::{
1515

1616
// Import parser types from crate library
1717
use bbl_parser::parser::{
18-
parse_frame_data, BBLDataStream, ENCODING_NEG_14BIT, ENCODING_NULL, ENCODING_SIGNED_VB,
19-
ENCODING_TAG2_3S32, ENCODING_UNSIGNED_VB,
18+
parse_e_frame, parse_frame_data, parse_h_frame, parse_s_frame, BBLDataStream,
2019
};
2120

2221
// Import types from crate library
23-
use bbl_parser::types::FrameDefinition;
22+
use bbl_parser::types::{EventFrame, FrameDefinition};
2423

2524
/// Maximum recursion depth to prevent stack overflow
2625
const MAX_RECURSION_DEPTH: usize = 100;
@@ -300,16 +299,6 @@ struct GpsHomeCoordinate {
300299
timestamp_us: u64,
301300
}
302301

303-
// Event structure for JSON export
304-
#[derive(Debug, Clone)]
305-
struct EventFrame {
306-
timestamp_us: u64,
307-
event_type: u8,
308-
#[allow(dead_code)]
309-
event_data: Vec<u8>,
310-
event_name: String,
311-
}
312-
313302
#[derive(Debug)]
314303
struct BBLLog {
315304
log_number: usize,
@@ -2304,310 +2293,9 @@ fn parse_frames(
23042293
))
23052294
}
23062295

2307-
#[allow(dead_code)]
2308-
fn parse_i_frame(
2309-
stream: &mut BBLDataStream,
2310-
frame_def: &FrameDefinition,
2311-
debug: bool,
2312-
) -> Result<HashMap<String, i32>> {
2313-
let mut data = HashMap::new();
2314-
2315-
// Parse each field according to the frame definition
2316-
for field in &frame_def.fields {
2317-
let value = match field.encoding {
2318-
ENCODING_SIGNED_VB => stream.read_signed_vb()?,
2319-
ENCODING_UNSIGNED_VB => stream.read_unsigned_vb()? as i32,
2320-
ENCODING_NEG_14BIT => stream.read_neg_14bit()?,
2321-
ENCODING_NULL => 0,
2322-
_ => {
2323-
if debug {
2324-
println!(
2325-
"Unsupported I-frame encoding {} for field {}",
2326-
field.encoding, field.name
2327-
);
2328-
}
2329-
0
2330-
}
2331-
};
2332-
2333-
data.insert(field.name.clone(), value);
2334-
}
2335-
2336-
Ok(data)
2337-
}
2338-
2339-
fn parse_s_frame(
2340-
stream: &mut BBLDataStream,
2341-
frame_def: &FrameDefinition,
2342-
debug: bool,
2343-
) -> Result<HashMap<String, i32>> {
2344-
let mut data = HashMap::new();
2345-
let mut field_index = 0;
2346-
2347-
while field_index < frame_def.fields.len() {
2348-
let field = &frame_def.fields[field_index];
2349-
2350-
match field.encoding {
2351-
ENCODING_SIGNED_VB => {
2352-
let value = stream.read_signed_vb()?;
2353-
data.insert(field.name.clone(), value);
2354-
field_index += 1;
2355-
}
2356-
ENCODING_UNSIGNED_VB => {
2357-
let value = stream.read_unsigned_vb()? as i32;
2358-
data.insert(field.name.clone(), value);
2359-
field_index += 1;
2360-
}
2361-
ENCODING_NEG_14BIT => {
2362-
let value = stream.read_neg_14bit()?;
2363-
data.insert(field.name.clone(), value);
2364-
field_index += 1;
2365-
}
2366-
ENCODING_TAG2_3S32 => {
2367-
// This encoding handles 3 fields at once
2368-
let mut values = [0i32; 8];
2369-
stream.read_tag2_3s32(&mut values)?;
2370-
2371-
#[allow(clippy::needless_range_loop)]
2372-
for j in 0..3 {
2373-
if field_index + j < frame_def.fields.len() {
2374-
let current_field = &frame_def.fields[field_index + j];
2375-
data.insert(current_field.name.clone(), values[j]);
2376-
}
2377-
}
2378-
field_index += 3;
2379-
}
2380-
ENCODING_NULL => {
2381-
data.insert(field.name.clone(), 0);
2382-
field_index += 1;
2383-
}
2384-
_ => {
2385-
if debug {
2386-
println!(
2387-
"Unsupported S-frame encoding {} for field {}",
2388-
field.encoding, field.name
2389-
);
2390-
}
2391-
// For unsupported encodings, try to read as signed VB
2392-
let value = stream.read_signed_vb().unwrap_or(0);
2393-
data.insert(field.name.clone(), value);
2394-
field_index += 1;
2395-
}
2396-
}
2397-
}
2398-
2399-
Ok(data)
2400-
}
2401-
2402-
fn parse_h_frame(
2403-
stream: &mut BBLDataStream,
2404-
frame_def: &FrameDefinition,
2405-
debug: bool,
2406-
) -> Result<HashMap<String, i32>> {
2407-
let mut data = HashMap::new();
2408-
2409-
if debug {
2410-
println!("Parsing H frame with {} fields", frame_def.count);
2411-
}
2412-
2413-
// H frames contain GPS home position data
2414-
for (i, field) in frame_def.fields.iter().enumerate() {
2415-
if i >= frame_def.count {
2416-
break;
2417-
}
2418-
2419-
let value = match field.encoding {
2420-
ENCODING_SIGNED_VB => stream.read_signed_vb()?,
2421-
ENCODING_UNSIGNED_VB => stream.read_unsigned_vb()? as i32,
2422-
ENCODING_NEG_14BIT => stream.read_neg_14bit()?,
2423-
ENCODING_NULL => 0,
2424-
_ => {
2425-
if debug {
2426-
println!(
2427-
"Unsupported H-frame encoding {} for field {}",
2428-
field.encoding, field.name
2429-
);
2430-
}
2431-
stream.read_signed_vb().unwrap_or(0)
2432-
}
2433-
};
2434-
2435-
data.insert(field.name.clone(), value);
2436-
}
2437-
2438-
Ok(data)
2439-
}
2440-
24412296
// Note: parse_g_frame is no longer used - G frames now use differential encoding
24422297
// like P frames in the main parsing loop for correct GPS coordinate calculation
24432298

2444-
// Parse E frames (Event frames) - based on C reference implementation
2445-
fn parse_e_frame(stream: &mut BBLDataStream, debug: bool) -> Result<EventFrame> {
2446-
if debug {
2447-
println!("Parsing E frame (Event frame)");
2448-
}
2449-
2450-
// Read event type (1 byte)
2451-
let event_type = stream.read_byte()?;
2452-
2453-
// Read event data - the length depends on the event type
2454-
let mut event_data = Vec::new();
2455-
let event_name = match event_type {
2456-
0 => {
2457-
// FLIGHT_LOG_EVENT_SYNC_BEEP
2458-
"Sync beep".to_string()
2459-
}
2460-
1 => {
2461-
// FLIGHT_LOG_EVENT_AUTOTUNE_CYCLE_START
2462-
"Autotune cycle start".to_string()
2463-
}
2464-
2 => {
2465-
// FLIGHT_LOG_EVENT_AUTOTUNE_CYCLE_RESULT
2466-
let axis = stream.read_byte()?;
2467-
let p_gain = stream.read_signed_vb()? as f32 / 1000.0;
2468-
let i_gain = stream.read_signed_vb()? as f32 / 1000.0;
2469-
let d_gain = stream.read_signed_vb()? as f32 / 1000.0;
2470-
event_data.extend_from_slice(&[axis]);
2471-
format!(
2472-
"Autotune cycle result - Axis: {}, P: {:.3}, I: {:.3}, D: {:.3}",
2473-
axis, p_gain, i_gain, d_gain
2474-
)
2475-
}
2476-
3 => {
2477-
// FLIGHT_LOG_EVENT_AUTOTUNE_TARGETS
2478-
let current_angle = stream.read_signed_vb()?;
2479-
let target_angle = stream.read_signed_vb()?;
2480-
let target_angle_at_peak = stream.read_signed_vb()?;
2481-
let first_peak_angle = stream.read_signed_vb()?;
2482-
let second_peak_angle = stream.read_signed_vb()?;
2483-
format!("Autotune targets - Current: {}, Target: {}, Peak target: {}, First peak: {}, Second peak: {}",
2484-
current_angle, target_angle, target_angle_at_peak, first_peak_angle, second_peak_angle)
2485-
}
2486-
4 => {
2487-
// FLIGHT_LOG_EVENT_INFLIGHT_ADJUSTMENT
2488-
let adjustment_function = stream.read_byte()?;
2489-
if adjustment_function > 127 {
2490-
// Float value
2491-
let new_value = stream.read_unsigned_vb()? as f32;
2492-
event_data.extend_from_slice(&[adjustment_function]);
2493-
format!(
2494-
"Inflight adjustment - Function: {}, New value: {:.3}",
2495-
adjustment_function, new_value
2496-
)
2497-
} else {
2498-
// Integer value
2499-
let new_value = stream.read_signed_vb()?;
2500-
event_data.extend_from_slice(&[adjustment_function]);
2501-
format!(
2502-
"Inflight adjustment - Function: {}, New value: {}",
2503-
adjustment_function, new_value
2504-
)
2505-
}
2506-
}
2507-
5 => {
2508-
// FLIGHT_LOG_EVENT_LOGGING_RESUME
2509-
let log_iteration = stream.read_unsigned_vb()?;
2510-
let current_time = stream.read_unsigned_vb()?;
2511-
format!(
2512-
"Logging resume - Iteration: {}, Time: {}",
2513-
log_iteration, current_time
2514-
)
2515-
}
2516-
6 => {
2517-
// FLIGHT_LOG_EVENT_LOG_END (old numbering)
2518-
// Read end message bytes
2519-
for _ in 0..4 {
2520-
if !stream.eof {
2521-
event_data.push(stream.read_byte()?);
2522-
}
2523-
}
2524-
"Log end".to_string()
2525-
}
2526-
10 => {
2527-
// FLIGHT_LOG_EVENT_AUTOTUNE_CYCLE_START (UNUSED)
2528-
"Autotune cycle start (unused)".to_string()
2529-
}
2530-
11 => {
2531-
// FLIGHT_LOG_EVENT_AUTOTUNE_CYCLE_RESULT (UNUSED)
2532-
"Autotune cycle result (unused)".to_string()
2533-
}
2534-
12 => {
2535-
// FLIGHT_LOG_EVENT_AUTOTUNE_TARGETS (UNUSED)
2536-
"Autotune targets (unused)".to_string()
2537-
}
2538-
13 => {
2539-
// FLIGHT_LOG_EVENT_INFLIGHT_ADJUSTMENT
2540-
let adjustment_function = stream.read_byte()?;
2541-
if adjustment_function > 127 {
2542-
let new_value = stream.read_unsigned_vb()? as f32;
2543-
event_data.extend_from_slice(&[adjustment_function]);
2544-
format!(
2545-
"Inflight adjustment - Function: {}, New value: {:.3}",
2546-
adjustment_function, new_value
2547-
)
2548-
} else {
2549-
let new_value = stream.read_signed_vb()?;
2550-
event_data.extend_from_slice(&[adjustment_function]);
2551-
format!(
2552-
"Inflight adjustment - Function: {}, New value: {}",
2553-
adjustment_function, new_value
2554-
)
2555-
}
2556-
}
2557-
14 => {
2558-
// FLIGHT_LOG_EVENT_LOGGING_RESUME
2559-
let log_iteration = stream.read_unsigned_vb()?;
2560-
let current_time = stream.read_unsigned_vb()?;
2561-
format!(
2562-
"Logging resume - Iteration: {}, Time: {}",
2563-
log_iteration, current_time
2564-
)
2565-
}
2566-
15 => {
2567-
// FLIGHT_LOG_EVENT_DISARM
2568-
"Disarm".to_string()
2569-
}
2570-
30 => {
2571-
// FLIGHT_LOG_EVENT_FLIGHTMODE - flight mode status event
2572-
// Read flight mode data
2573-
for _ in 0..4 {
2574-
if !stream.eof {
2575-
event_data.push(stream.read_byte()?);
2576-
}
2577-
}
2578-
"Flight mode change".to_string()
2579-
}
2580-
255 => {
2581-
// FLIGHT_LOG_EVENT_LOG_END
2582-
"Log end".to_string()
2583-
}
2584-
_ => {
2585-
// Unknown event type - read a few bytes as data
2586-
for _ in 0..8 {
2587-
if stream.eof {
2588-
break;
2589-
}
2590-
event_data.push(stream.read_byte()?);
2591-
}
2592-
format!("Unknown event type: {}", event_type)
2593-
}
2594-
};
2595-
2596-
if debug {
2597-
println!(
2598-
"DEBUG: Event - Type: {}, Description: {}",
2599-
event_type, event_name
2600-
);
2601-
}
2602-
2603-
Ok(EventFrame {
2604-
timestamp_us: 0, // Will be set later from context
2605-
event_type,
2606-
event_data,
2607-
event_name,
2608-
})
2609-
}
2610-
26112299
fn skip_frame(stream: &mut BBLDataStream, frame_type: char, debug: bool) -> Result<()> {
26122300
if debug {
26132301
println!("Skipping {frame_type} frame");

0 commit comments

Comments
 (0)