Port radio_read_image to rust

This commit is contained in:
Greg Shuflin 2021-03-01 19:43:01 -08:00
parent 7a39fd1ae2
commit 98eaa63740
2 changed files with 74 additions and 99 deletions

84
radio.c
View File

@ -71,90 +71,6 @@ void set_active_device(radio_device_t* d) {
unsigned char radio_mem [1024*1024*2]; // Radio memory contents, up to 2 Mbytes
//
// Read firmware image from the binary file.
//
radio_device_t* radio_read_image(const char *filename)
{
FILE *img;
struct stat st;
char ident[8];
radio_device_t * dev = NULL;
fprintf(stderr, "Read codeplug from file '%s'.\n", filename);
img = fopen(filename, "rb");
if (! img) {
perror(filename);
exit(-1);
}
// Guess device type by file size.
if (stat(filename, &st) < 0) {
perror(filename);
exit(-1);
}
switch (st.st_size) {
case 851968:
case 852533:
dev = &radio_uv380;
break;
case 262144:
case 262709:
dev = &radio_md380;
break;
case 1606528:
if (fread(ident, 1, 8, img) != 8) {
fprintf(stderr, "%s: Cannot read header.\n", filename);
exit(-1);
}
fseek(img, 0, SEEK_SET);
if (memcmp(ident, "D868UVE", 7) == 0) {
dev = &radio_d868uv;
} else if (memcmp(ident, "D878UV", 6) == 0) {
dev = &radio_d878uv;
} else if (memcmp(ident, "D6X2UV", 6) == 0) {
dev = &radio_dmr6x2;
} else {
fprintf(stderr, "%s: Unrecognized header '%.6s'\n",
filename, ident);
exit(-1);
}
break;
case 131072:
if (fread(ident, 1, 8, img) != 8) {
fprintf(stderr, "%s: Cannot read header.\n", filename);
exit(-1);
}
if (memcmp(ident, "BF-5R", 5) == 0) {
dev = &radio_rd5r;
} else if (memcmp(ident, "MD-760P", 7) == 0) {
dev = &radio_gd77;
} else if (memcmp(ident, "1801", 4) == 0) {
dev = &radio_dm1801;
} else if (memcmp(ident, "MD-760", 6) == 0) {
fprintf(stderr, "Old Radioddity GD-77 v2.6 image not supported!\n");
exit(-1);
} else {
fprintf(stderr, "%s: Unrecognized header '%.6s'\n",
filename, ident);
exit(-1);
}
fseek(img, 0, SEEK_SET);
break;
default:
fprintf(stderr, "%s: Unrecognized file size %u bytes.\n",
filename, (int) st.st_size);
exit(-1);
}
dev->read_image(dev, img);
fclose(img);
set_active_device(dev);
return dev;
}
//
// Read the configuration from text file, and modify the firmware.
//

View File

@ -37,7 +37,6 @@ extern {
fn set_active_device(device: *const radio_device_t);
fn radio_print_config(device: *const radio_device_t, file: *const libc::FILE, verbose: c_int);
fn radio_read_image(filename: *const c_char) -> *const radio_device_t;
fn radio_parse_config(device: *const radio_device_t, filename: *const c_char);
fn radio_write_csv(device: *const radio_device_t, filename: *const c_char);
@ -189,38 +188,98 @@ pub fn verify_config(radio: &Radio) {
/// Read firmware image from the binary file.
pub fn read_image(filename: &str) -> Radio {
use std::io::{Seek, SeekFrom, Read};
/*
eprintln!"Read codeplug from file '{}'.", filename);
let img = std::fs::File::open(filename).unwrap();
let metadata = std::fs::metadata(filename).unwrap();
let file_size = metadata.len();
match file_size {
851968 | 852533 => {
}
262144 | 262709 => {
}
1606528 => {
}
131072 => {
}
size => {
eprintln!("{}: Unrecognized file size {} bytes.", filename, size);
fn read_header(file: &mut std::fs::File, filename: &str) -> Vec<u8> {
let mut header_buf: [u8; 7] = [0; 7];
match file.read(&mut header_buf) {
Ok(7) => (),
Ok(_) => {
eprintln!("{}: Cannot read header.", filename);
exit(-1);
},
Err(e) => {
eprintln!("{}: Cannot read header. Error: {}", filename, e);
exit(-1);
}
};
*/
let filename = CString::new(filename.to_string()).unwrap();
let ptr = unsafe {
radio_read_image(filename.as_ptr())
file.seek(SeekFrom::Start(0)).unwrap();
header_buf.to_vec()
}
eprintln!("Read codeplug from file '{}'.", filename);
let mut img_file = std::fs::File::open(filename).unwrap();
let metadata = std::fs::metadata(filename).unwrap();
let file_size = metadata.len();
let device = unsafe {match file_size {
851968 | 852533 => {
&radio_uv380
}
262144 | 262709 => {
&radio_md380
}
1606528 => {
let header = read_header(&mut img_file, filename);
if header.as_slice().starts_with(b"D868UVE") {
&radio_d868uv
} else if header.as_slice().starts_with(b"D878UV") {
&radio_d878uv
} else if header.as_slice().starts_with(b"D6X2UV") {
&radio_dmr6x2
} else {
match std::str::from_utf8(&header) {
Ok(s) => eprintln!("Unrecognized header: {}", s),
Err(_) => eprintln!("Unrecognized header: {:?}", header),
};
Radio { ptr: ptr as *mut radio_device_t }
exit(-1)
}
}
131072 => {
let header = read_header(&mut img_file, filename);
if header.as_slice().starts_with(b"BF-5R") {
&radio_rd5r
} else if header.as_slice().starts_with(b"MD-760P") {
&radio_gd77
} else if header.as_slice().starts_with(b"1801") {
&radio_dm1801
} else if header.as_slice().starts_with(b"MD-760") {
eprintln!("Old Radioddity GD-77 v2.6 image not supported!");
exit(-1)
} else {
match std::str::from_utf8(&header) {
Ok(s) => eprintln!("Unrecognized header: {}", s),
Err(_) => eprintln!("Unrecognized header: {:?}", header),
};
exit(-1)
}
}
size => {
eprintln!("{}: Unrecognized file size {} bytes.", filename, size);
exit(-1)
}
} };
let fd = img_file.as_raw_fd();
let mode = CString::new("rb").unwrap();
unsafe {
let device = device as *const radio_device_t;
let device = device as *mut radio_device_t;
let file = libc::fdopen(fd, mode.as_ptr());
let read_image_fn = (*device).read_image.unwrap();
read_image_fn(device, file);
libc::fclose(file);
set_active_device(device);
Radio { ptr: device }
}
}
/// Save firmware image to the binary file.