dmrconfig/src/radio.rs

142 lines
3.6 KiB
Rust

use std::ffi::CString;
use libc::{c_char, c_int};
use std::os::unix::io::AsRawFd;
#[repr(C)]
pub struct RadioDeviceT { _private: [u8; 0] }
extern {
fn radio_connect() -> *const RadioDeviceT;
fn radio_download(device: *const RadioDeviceT);
fn radio_upload(device: *const RadioDeviceT, cont_flag: c_int);
fn radio_list_c();
fn radio_verify_config(device: *const RadioDeviceT);
fn radio_print_version(device: *const RadioDeviceT, stdout: *const libc::FILE);
fn radio_print_config(device: *const RadioDeviceT, file: *const libc::FILE, verbose: c_int);
fn radio_read_image(filename: *const c_char) -> *const RadioDeviceT;
fn radio_save_image(device: *const RadioDeviceT, filename: *const c_char);
fn radio_parse_config(device: *const RadioDeviceT, filename: *const c_char);
fn radio_write_csv(device: *const RadioDeviceT, filename: *const c_char);
fn dfu_reboot();
fn dfu_close();
fn hid_close();
fn serial_close();
}
/// Connect to the radio via the serial port.
/// Identify the type of device.
pub fn connect() -> *const RadioDeviceT {
unsafe {
radio_connect()
}
}
/// Close the serial port.
pub fn disconnect() {
eprintln!("Close device.");
unsafe {
// Restore the normal radio mode.
dfu_reboot();
dfu_close();
hid_close();
serial_close();
}
}
/// Read firmware image from the device
pub fn download(device: *const RadioDeviceT) {
unsafe {
radio_download(device)
}
}
/// Write firmware image to the device.
pub fn upload(device: *const RadioDeviceT, cont_flag: c_int) {
unsafe {
radio_upload(device, cont_flag)
}
}
/// List all supported radios.
pub fn list() {
unsafe {
radio_list_c();
}
}
/// Check the configuration.
pub fn verify_config(device: *const RadioDeviceT) {
unsafe {
radio_verify_config(device);
}
}
/// Read firmware image from the binary file.
pub fn read_image(filename: &str) -> *const RadioDeviceT {
let filename = CString::new(filename.to_string()).unwrap();
unsafe {
radio_read_image(filename.as_ptr())
}
}
/// Save firmware image to the binary file.
pub fn save_image(device: *const RadioDeviceT, filename: &str) {
let filename = CString::new(filename.to_string()).unwrap();
unsafe {
radio_save_image(device, filename.as_ptr())
}
}
/// Read the configuration from text file, and modify the firmware.
pub fn parse_config(device: *const RadioDeviceT, filename: &str) {
let filename = CString::new(filename.to_string()).unwrap();
unsafe {
radio_parse_config(device, filename.as_ptr())
}
}
/// Print full information about the device configuration.
pub fn print_config(device: *const RadioDeviceT, filename: &str) {
let file = std::fs::File::create(filename).unwrap();
let fd = file.as_raw_fd();
let mode = CString::new("w").unwrap();
unsafe {
let file =libc::fdopen(fd, mode.as_ptr());
radio_print_config(device, file, 1);
libc::fclose(file);
}
}
pub fn print_config_to_stdout(device: *const RadioDeviceT) {
let mode = CString::new("w").unwrap();
unsafe {
let stdout = libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr());
let verbosity = if libc::isatty(libc::STDOUT_FILENO) == 1 {
0
} else {
1
};
radio_print_config(device, stdout, verbosity);
}
}
/// Print generic information about the device.
pub fn print_version(device: *const RadioDeviceT) {
let mode = CString::new("w").unwrap();
unsafe {
radio_print_version(device, libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr()));
}
}
/// Update CSV contacts database.
pub fn write_csv(device: *const RadioDeviceT, filename: &str) {
let filename = CString::new(filename.to_string()).unwrap();
unsafe {
radio_write_csv(device, filename.as_ptr());
}
}