diff --git a/radio.c b/radio.c index 104bb31..a818318 100644 --- a/radio.c +++ b/radio.c @@ -58,11 +58,11 @@ static struct { { 0, 0 } }; +static radio_device_t *device; // Device-dependent interface + unsigned char radio_mem [1024*1024*2]; // Radio memory contents, up to 2 Mbytes int radio_progress; // Read/write progress counter -static radio_device_t *device; // Device-dependent interface - // // Close the serial port. // @@ -92,6 +92,7 @@ radio_device_t* radio_connect() { const char *ident; int i; + radio_device_t * dev = 0; // Try TYT MD family. ident = dfu_init(0x0483, 0xdf11); @@ -113,16 +114,18 @@ radio_device_t* radio_connect() for (i=0; radio_tab[i].ident; i++) { if (strcasecmp(ident, radio_tab[i].ident) == 0) { - device = radio_tab[i].device; + dev = radio_tab[i].device; break; } } - if (! device) { + if (! dev) { fprintf(stderr, "Unrecognized radio '%s'.\n", ident); exit(-1); } - fprintf(stderr, "Connect to %s.\n", device->name); - return device; + fprintf(stderr, "Connect to %s.\n", dev->name); + + device = dev; + return dev; } // @@ -179,11 +182,12 @@ void radio_upload(radio_device_t* dev, int cont_flag) // // Read firmware image from the binary file. // -void radio_read_image(const char *filename) +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"); @@ -200,11 +204,11 @@ void radio_read_image(const char *filename) switch (st.st_size) { case 851968: case 852533: - device = &radio_uv380; + dev = &radio_uv380; break; case 262144: case 262709: - device = &radio_md380; + dev = &radio_md380; break; case 1606528: if (fread(ident, 1, 8, img) != 8) { @@ -213,11 +217,11 @@ void radio_read_image(const char *filename) } fseek(img, 0, SEEK_SET); if (memcmp(ident, "D868UVE", 7) == 0) { - device = &radio_d868uv; + dev = &radio_d868uv; } else if (memcmp(ident, "D878UV", 6) == 0) { - device = &radio_d878uv; + dev = &radio_d878uv; } else if (memcmp(ident, "D6X2UV", 6) == 0) { - device = &radio_dmr6x2; + dev = &radio_dmr6x2; } else { fprintf(stderr, "%s: Unrecognized header '%.6s'\n", filename, ident); @@ -230,11 +234,11 @@ void radio_read_image(const char *filename) exit(-1); } if (memcmp(ident, "BF-5R", 5) == 0) { - device = &radio_rd5r; + dev = &radio_rd5r; } else if (memcmp(ident, "MD-760P", 7) == 0) { - device = &radio_gd77; + dev = &radio_gd77; } else if (memcmp(ident, "1801", 4) == 0) { - device = &radio_dm1801; + 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); @@ -251,14 +255,18 @@ void radio_read_image(const char *filename) exit(-1); } - device->read_image(device, img); + + dev->read_image(dev, img); fclose(img); + + device = dev; + return dev; } // // Save firmware image to the binary file. // -void radio_save_image(const char *filename) +void radio_save_image(radio_device_t* device, const char *filename) { FILE *img; @@ -275,7 +283,7 @@ void radio_save_image(const char *filename) // // Read the configuration from text file, and modify the firmware. // -void radio_parse_config(const char *filename) +void radio_parse_config(radio_device_t* device, const char *filename) { FILE *conf; char line [256], *p, *v; @@ -358,7 +366,7 @@ badline: fprintf(stderr, "Invalid line: '%s'\n", line); // // Print full information about the device configuration. // -void radio_print_config(FILE *out, int verbose) +void radio_print_config(radio_device_t* device, FILE *out, int verbose) { if (verbose) { char buf [40]; @@ -380,7 +388,7 @@ void radio_print_config(FILE *out, int verbose) // // Check the configuration is correct. // -void radio_verify_config() +void radio_verify_config(radio_device_t* device) { if (!device->verify_config(device)) { // Message should be already printed. @@ -391,7 +399,7 @@ void radio_verify_config() // // Update contacts database on the device. // -void radio_write_csv(const char *filename) +void radio_write_csv(radio_device_t* device, const char *filename) { FILE *csv; diff --git a/src/lib.rs b/src/lib.rs index e70d089..8f5a348 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -109,17 +109,17 @@ pub extern "C" fn rust_main(_argc: c_int, _argv: *const *const c_char) -> c_int let device = radio::connect(); //NOTE this changes the semantics of the program radio::read_image(&img); radio::print_version(device); - radio::parse_config(&config_filename); - radio::verify_config(); - radio::save_image("device.img"); + radio::parse_config(device, &config_filename); + radio::verify_config(device); + radio::save_image(device, "device.img"); } else { // Update device from text config file. let device = radio::connect(); radio::download(device); radio::print_version(device); - radio::save_image("device.img"); - radio::parse_config(&config_filename); - radio::verify_config(); + radio::save_image(device, "device.img"); + radio::parse_config(device, &config_filename); + radio::verify_config(device); radio::upload(device, 1); radio::disconnect(); } @@ -128,9 +128,9 @@ pub extern "C" fn rust_main(_argc: c_int, _argv: *const *const c_char) -> c_int print_usage(); } // Verify text config file. - radio::connect(); - radio::parse_config(&matches.free[0]); - radio::verify_config(); + let device = radio::connect(); + radio::parse_config(device, &matches.free[0]); + radio::verify_config(device); radio::disconnect(); } else if read_flag { if matches.free.len() != 0 { @@ -142,28 +142,28 @@ pub extern "C" fn rust_main(_argc: c_int, _argv: *const *const c_char) -> c_int radio::download(device); radio::print_version(device); radio::disconnect(); - radio::save_image("device.img"); + radio::save_image(device, "device.img"); // Print configuration to file. let filename = "device.conf"; println!("Print configuration to file '{}.", filename); - radio::print_config(filename); + radio::print_config(device, filename); } else if csv_flag { if matches.free.len() != 1 { print_usage(); } - radio::connect(); - radio::write_csv(&matches.free[0]); + let device = radio::connect(); + radio::write_csv(device, &matches.free[0]); radio::disconnect(); } else { if matches.free.len() != 1 { print_usage(); } - radio::read_image(&matches.free[0]); - radio::print_config_to_stdout(); + let device = radio::read_image(&matches.free[0]); + radio::print_config_to_stdout(device); } exit(0); diff --git a/src/radio.rs b/src/radio.rs index fd5a240..d832b98 100644 --- a/src/radio.rs +++ b/src/radio.rs @@ -11,13 +11,13 @@ extern { fn radio_download(device: *const RadioDeviceT); fn radio_upload(device: *const RadioDeviceT, cont_flag: c_int); fn radio_list_c(); - fn radio_verify_config(); + fn radio_verify_config(device: *const RadioDeviceT); fn radio_print_version(device: *const RadioDeviceT, stdout: *const libc::FILE); - fn radio_print_config(file: *const libc::FILE, verbose: c_int); - fn radio_read_image(filename: *const c_char); - fn radio_save_image(filename: *const c_char); - fn radio_parse_config(filename: *const c_char); - fn radio_write_csv(filename: *const c_char); + 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); } /// Connect to the radio via the serial port. @@ -58,49 +58,49 @@ pub fn list() { } /// Check the configuration. -pub fn verify_config() { +pub fn verify_config(device: *const RadioDeviceT) { unsafe { - radio_verify_config(); + radio_verify_config(device); } } /// Read firmware image from the binary file. -pub fn read_image(filename: &str) { +pub fn read_image(filename: &str) -> *const RadioDeviceT { let filename = CString::new(filename.to_string()).unwrap(); unsafe { - radio_read_image(filename.as_ptr()); + radio_read_image(filename.as_ptr()) } } /// Save firmware image to the binary file. -pub fn save_image(filename: &str) { +pub fn save_image(device: *const RadioDeviceT, filename: &str) { let filename = CString::new(filename.to_string()).unwrap(); unsafe { - radio_save_image(filename.as_ptr()) + radio_save_image(device, filename.as_ptr()) } } /// Read the configuration from text file, and modify the firmware. -pub fn parse_config(filename: &str) { +pub fn parse_config(device: *const RadioDeviceT, filename: &str) { let filename = CString::new(filename.to_string()).unwrap(); unsafe { - radio_parse_config(filename.as_ptr()) + radio_parse_config(device, filename.as_ptr()) } } /// Print full information about the device configuration. -pub fn print_config(filename: &str) { +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(file, 1); + radio_print_config(device, file, 1); libc::fclose(file); } } -pub fn print_config_to_stdout() { +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()); @@ -109,7 +109,7 @@ pub fn print_config_to_stdout() { } else { 1 }; - radio_print_config(stdout, verbosity); + radio_print_config(device, stdout, verbosity); } } @@ -122,9 +122,9 @@ pub fn print_version(device: *const RadioDeviceT) { } /// Update CSV contacts database. -pub fn write_csv(filename: &str) { +pub fn write_csv(device: *const RadioDeviceT, filename: &str) { let filename = CString::new(filename.to_string()).unwrap(); unsafe { - radio_write_csv(filename.as_ptr()); + radio_write_csv(device, filename.as_ptr()); } }