parse_config port to rust
This commit is contained in:
parent
5658759cf3
commit
3f4b18368b
106
radio.c
106
radio.c
@ -35,109 +35,3 @@
|
|||||||
#include "radio.h"
|
#include "radio.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/*
|
|
||||||
typedef struct { char* ident; radio_device_t* device; } radio_tab_t;
|
|
||||||
|
|
||||||
static radio_tab_t radio_tab[] = {
|
|
||||||
{ "DR780", &radio_md380 }, // TYT MD-380, Retevis RT3, RT8
|
|
||||||
{ "MD390", &radio_md390 }, // TYT MD-390
|
|
||||||
{ "MD-UV380", &radio_uv380 }, // TYT MD-UV380
|
|
||||||
{ "MD-UV390", &radio_uv390 }, // TYT MD-UV390, Retevis RT3S
|
|
||||||
{ "2017", &radio_md2017 }, // TYT MD-2017, Retevis RT82
|
|
||||||
{ "MD9600", &radio_md9600 }, // TYT MD-9600
|
|
||||||
{ "BF-5R", &radio_rd5r }, // Baofeng RD-5R, TD-5R
|
|
||||||
{ "1801", &radio_dm1801 }, // Baofeng DM-1801
|
|
||||||
{ "DM-1701", &radio_rt84 }, // Baofeng DM-1701, Retevis RT84
|
|
||||||
{ "MD-760P", &radio_gd77 }, // Radioddity GD-77, version 3.1.1 and later
|
|
||||||
{ "D868UVE", &radio_d868uv }, // Anytone AT-D868UV
|
|
||||||
{ "D878UV", &radio_d878uv }, // Anytone AT-D878UV
|
|
||||||
{ "D6X2UV", &radio_dmr6x2 }, // BTECH DMR-6x2
|
|
||||||
{ "ZD3688", &radio_d900 }, // Zastone D900
|
|
||||||
{ "TP660", &radio_dp880 }, // Zastone DP880
|
|
||||||
{ "ZN><:", &radio_rt27d }, // Radtel RT-27D
|
|
||||||
{ 0, 0 }
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read the configuration from text file, and modify the firmware.
|
|
||||||
//
|
|
||||||
void radio_parse_config(radio_device_t* device, const char *filename)
|
|
||||||
{
|
|
||||||
FILE *conf;
|
|
||||||
char line [256], *p, *v;
|
|
||||||
int table_id = 0, table_dirty = 0;
|
|
||||||
|
|
||||||
fprintf(stderr, "Read configuration from file '%s'.\n", filename);
|
|
||||||
conf = fopen(filename, "r");
|
|
||||||
if (! conf) {
|
|
||||||
perror(filename);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
device->channel_count = 0;
|
|
||||||
while (fgets(line, sizeof(line), conf)) {
|
|
||||||
line[sizeof(line)-1] = 0;
|
|
||||||
|
|
||||||
// Strip comments.
|
|
||||||
v = strchr(line, '#');
|
|
||||||
if (v)
|
|
||||||
*v = 0;
|
|
||||||
|
|
||||||
// Strip trailing spaces and newline.
|
|
||||||
v = line + strlen(line) - 1;
|
|
||||||
while (v >= line && (*v=='\n' || *v=='\r' || *v==' ' || *v=='\t'))
|
|
||||||
*v-- = 0;
|
|
||||||
|
|
||||||
// Ignore comments and empty lines.
|
|
||||||
p = line;
|
|
||||||
if (*p == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (*p != ' ') {
|
|
||||||
// Table finished.
|
|
||||||
table_id = 0;
|
|
||||||
|
|
||||||
// Find the value.
|
|
||||||
v = strchr(p, ':');
|
|
||||||
if (! v) {
|
|
||||||
// Table header: get table type.
|
|
||||||
table_id = device->parse_header(device, p);
|
|
||||||
if (! table_id) {
|
|
||||||
badline: fprintf(stderr, "Invalid line: '%s'\n", line);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
table_dirty = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parameter.
|
|
||||||
*v++ = 0;
|
|
||||||
|
|
||||||
// Skip spaces.
|
|
||||||
while (*v == ' ' || *v == '\t')
|
|
||||||
v++;
|
|
||||||
|
|
||||||
device->parse_parameter(device, p, v);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Table row or comment.
|
|
||||||
// Skip spaces.
|
|
||||||
// Ignore comments and empty lines.
|
|
||||||
while (*p == ' ' || *p == '\t')
|
|
||||||
p++;
|
|
||||||
if (*p == '#' || *p == 0)
|
|
||||||
continue;
|
|
||||||
if (! table_id) {
|
|
||||||
goto badline;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! device->parse_row(device, table_id, ! table_dirty, p)) {
|
|
||||||
goto badline;
|
|
||||||
}
|
|
||||||
table_dirty = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(conf);
|
|
||||||
device->update_timestamp(device);
|
|
||||||
}
|
|
||||||
|
97
src/radio.rs
97
src/radio.rs
@ -37,8 +37,6 @@ pub static mut radio_mem: [u8; 1024*1024*2] = [0; 1024*1024*2];
|
|||||||
|
|
||||||
extern {
|
extern {
|
||||||
|
|
||||||
fn radio_parse_config(device: *const radio_device_t, filename: *const c_char);
|
|
||||||
|
|
||||||
fn dfu_init(vid: c_uint, pid: c_uint) -> *const c_char;
|
fn dfu_init(vid: c_uint, pid: c_uint) -> *const c_char;
|
||||||
fn dfu_reboot();
|
fn dfu_reboot();
|
||||||
fn dfu_close();
|
fn dfu_close();
|
||||||
@ -311,12 +309,99 @@ pub fn save_image(radio: &Radio, filename: &str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the configuration from text file, and modify the firmware.
|
/// Read the configuration from a text file, and modify the firmware.
|
||||||
pub fn parse_config(radio: &Radio, filename: &str) {
|
pub fn parse_config(radio: &Radio, filename: &str) {
|
||||||
let device = radio.ptr;
|
use std::io::{BufRead, BufReader};
|
||||||
let filename = CString::new(filename.to_string()).unwrap();
|
|
||||||
|
let device = radio.ptr as *mut radio_device_t;
|
||||||
|
|
||||||
|
let parse_header_fn = unsafe {
|
||||||
|
(*device).parse_header.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let parse_parameter_fn = unsafe {
|
||||||
|
(*device).parse_parameter.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let parse_row_fn = unsafe {
|
||||||
|
(*device).parse_row.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let update_timestamp_fn = unsafe {
|
||||||
|
(*device).update_timestamp.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
eprintln!("Read configuration from file '{}'.", filename);
|
||||||
|
let file = std::fs::File::open(filename).unwrap();
|
||||||
|
let file = BufReader::new(file);
|
||||||
|
|
||||||
|
let mut table_id: c_int = 0;
|
||||||
|
let mut table_dirty: c_int = 0;
|
||||||
|
|
||||||
|
for line in file.lines() {
|
||||||
|
let line = line.unwrap();
|
||||||
|
// Strip text after comment marker '#'
|
||||||
|
let trimmed_line = line
|
||||||
|
.split('#')
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.trim_end();
|
||||||
|
|
||||||
|
// Skip comments and blank lines
|
||||||
|
if trimmed_line.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Table row
|
||||||
|
if trimmed_line.chars().nth(0) == Some(' ') {
|
||||||
|
if table_id == 0 {
|
||||||
|
eprintln!("Invalid line: '{}'", line);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let trimmed_more = CString::new(trimmed_line.trim_start()).unwrap();
|
||||||
|
let ptr = trimmed_more.as_ptr() as *mut c_char;
|
||||||
|
let output = unsafe { parse_row_fn(device, table_id, !table_dirty, ptr) };
|
||||||
|
if output == 0 {
|
||||||
|
eprintln!("Invalid line: '{}'", line);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
table_dirty = 1;
|
||||||
|
} else {
|
||||||
|
// Table finished
|
||||||
|
table_id = 0;
|
||||||
|
|
||||||
|
// Find the value
|
||||||
|
if let Some(colon_byte_idx) = line.find(':') {
|
||||||
|
|
||||||
|
let (param_str, value_str) = line.split_at(colon_byte_idx);
|
||||||
|
let stripped_value_str = value_str.strip_prefix(':').unwrap();
|
||||||
|
|
||||||
|
let param_c_str = CString::new(param_str.trim_start()).unwrap();
|
||||||
|
let param_ptr = param_c_str.as_ptr() as *mut c_char;
|
||||||
|
|
||||||
|
let value_c_str = CString::new(stripped_value_str.trim_start()).unwrap();
|
||||||
|
let value_ptr = value_c_str.as_ptr() as *mut c_char;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
parse_parameter_fn(device, param_ptr, value_ptr);
|
||||||
|
}
|
||||||
|
} else { // Table header
|
||||||
|
let c_line = CString::new(trimmed_line).unwrap();
|
||||||
|
let ptr = c_line.as_ptr() as *mut c_char;
|
||||||
|
table_id = unsafe { parse_header_fn(device, ptr) };
|
||||||
|
|
||||||
|
if table_id == 0 {
|
||||||
|
eprintln!("Invalid line: '{}'", line);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
table_dirty = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
radio_parse_config(device, filename.as_ptr())
|
update_timestamp_fn(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user