use anyhow::{bail, Context}; use subprocess::{Popen, PopenConfig, Redirection}; use crate::packet::RawPacket; // TODO eventually rewrite Ssdv in Rust? // Don't want to use FFI because then segfaults can hurt us pub fn ssdv_encode(callsign: &str, img: &[u8], img_idx: u8) -> anyhow::Result<Vec<RawPacket>> { let mut p = Popen::create( &[ "ssdv", "-e", "-c", callsign, "-n", "-q", "6", "-i", &format!("{}", img_idx), ], PopenConfig { stdin: Redirection::Pipe, stdout: Redirection::Pipe, stderr: Redirection::Pipe, ..Default::default() }, )?; let (stdout, stderr) = p.communicate_bytes(Some(img))?; if let Some(stderr) = stderr { if !stderr.is_empty() { eprintln!("{}", String::from_utf8_lossy(&stderr)); } } let stdout = stdout.context("ssdv no stdout")?; if stdout.len() % 256 != 0 { bail!("ssdv returned garbage"); } let mut out = vec![]; let mut cur = [0; 256]; let mut i = 0; for c in stdout { cur[i] = c; i += 1; if i == 256 { out.push(RawPacket(cur)); i = 0; } } Ok(out) }