Use bindgen for rust bindings
This commit is contained in:
parent
cece963e91
commit
e8099fc681
@ -12,3 +12,6 @@ crate-type = ["staticlib"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
getopts = "0.2"
|
getopts = "0.2"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
bindgen = "0.53.1"
|
||||||
|
32
build.rs
Normal file
32
build.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
extern crate bindgen;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Tell cargo to invalidate the built crate whenever the wrapper changes
|
||||||
|
println!("cargo:rerun-if-changed=radio.h");
|
||||||
|
|
||||||
|
// The bindgen::Builder is the main entry point
|
||||||
|
// to bindgen, and lets you build up options for
|
||||||
|
// the resulting bindings.
|
||||||
|
let bindings = bindgen::Builder::default()
|
||||||
|
// The input header we would like to generate
|
||||||
|
// bindings for.
|
||||||
|
.header("radio.h")
|
||||||
|
// Tell cargo to invalidate the built crate whenever any of the
|
||||||
|
// included header files changed.
|
||||||
|
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
||||||
|
.whitelist_type("radio_device_t")
|
||||||
|
// Finish the builder and generate the bindings.
|
||||||
|
.generate()
|
||||||
|
// Unwrap the Result and panic on failure.
|
||||||
|
.expect("Unable to generate bindings for radio.h");
|
||||||
|
|
||||||
|
// Write the bindings to the $OUT_DIR/bindings.rs file.
|
||||||
|
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||||
|
bindings
|
||||||
|
.write_to_file(out_path.join("bindings.rs"))
|
||||||
|
.expect("Couldn't write bindings!");
|
||||||
|
}
|
2
radio.h
2
radio.h
@ -29,6 +29,8 @@
|
|||||||
//
|
//
|
||||||
// Check for compatible radio model.
|
// Check for compatible radio model.
|
||||||
//
|
//
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
int radio_is_compatible(const char *ident);
|
int radio_is_compatible(const char *ident);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use libc::{c_int, c_char};
|
use libc::{c_int, c_char};
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
|
|
||||||
mod radio;
|
mod radio;
|
||||||
|
|
||||||
const COPYRIGHT: &'static str = "Copyright (C) 2018 Serge Vakulenko KK6ABQ";
|
const COPYRIGHT: &'static str = "Copyright (C) 2018 Serge Vakulenko KK6ABQ";
|
||||||
|
45
src/radio.rs
45
src/radio.rs
@ -2,22 +2,21 @@ use std::ffi::CString;
|
|||||||
use libc::{c_char, c_int};
|
use libc::{c_char, c_int};
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
#[repr(C)]
|
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||||
pub struct RadioDeviceT { _private: [u8; 0] }
|
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
fn radio_connect() -> *const RadioDeviceT;
|
fn radio_connect() -> *const radio_device_t;
|
||||||
|
|
||||||
fn radio_download(device: *const RadioDeviceT);
|
fn radio_download(device: *const radio_device_t);
|
||||||
fn radio_upload(device: *const RadioDeviceT, cont_flag: c_int);
|
fn radio_upload(device: *const radio_device_t, cont_flag: c_int);
|
||||||
fn radio_list_c();
|
fn radio_list_c();
|
||||||
fn radio_verify_config(device: *const RadioDeviceT);
|
fn radio_verify_config(device: *const radio_device_t);
|
||||||
fn radio_print_version(device: *const RadioDeviceT, stdout: *const libc::FILE);
|
fn radio_print_version(device: *const radio_device_t, stdout: *const libc::FILE);
|
||||||
fn radio_print_config(device: *const RadioDeviceT, file: *const libc::FILE, verbose: c_int);
|
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 RadioDeviceT;
|
fn radio_read_image(filename: *const c_char) -> *const radio_device_t;
|
||||||
fn radio_save_image(device: *const RadioDeviceT, filename: *const c_char);
|
fn radio_save_image(device: *const radio_device_t, filename: *const c_char);
|
||||||
fn radio_parse_config(device: *const RadioDeviceT, filename: *const c_char);
|
fn radio_parse_config(device: *const radio_device_t, filename: *const c_char);
|
||||||
fn radio_write_csv(device: *const RadioDeviceT, filename: *const c_char);
|
fn radio_write_csv(device: *const radio_device_t, filename: *const c_char);
|
||||||
|
|
||||||
fn dfu_reboot();
|
fn dfu_reboot();
|
||||||
fn dfu_close();
|
fn dfu_close();
|
||||||
@ -27,7 +26,7 @@ extern {
|
|||||||
|
|
||||||
/// Connect to the radio via the serial port.
|
/// Connect to the radio via the serial port.
|
||||||
/// Identify the type of device.
|
/// Identify the type of device.
|
||||||
pub fn connect() -> *const RadioDeviceT {
|
pub fn connect() -> *const radio_device_t {
|
||||||
unsafe {
|
unsafe {
|
||||||
radio_connect()
|
radio_connect()
|
||||||
}
|
}
|
||||||
@ -47,14 +46,14 @@ pub fn disconnect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Read firmware image from the device
|
/// Read firmware image from the device
|
||||||
pub fn download(device: *const RadioDeviceT) {
|
pub fn download(device: *const radio_device_t) {
|
||||||
unsafe {
|
unsafe {
|
||||||
radio_download(device)
|
radio_download(device)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write firmware image to the device.
|
/// Write firmware image to the device.
|
||||||
pub fn upload(device: *const RadioDeviceT, cont_flag: c_int) {
|
pub fn upload(device: *const radio_device_t, cont_flag: c_int) {
|
||||||
unsafe {
|
unsafe {
|
||||||
radio_upload(device, cont_flag)
|
radio_upload(device, cont_flag)
|
||||||
}
|
}
|
||||||
@ -69,14 +68,14 @@ pub fn list() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check the configuration.
|
/// Check the configuration.
|
||||||
pub fn verify_config(device: *const RadioDeviceT) {
|
pub fn verify_config(device: *const radio_device_t) {
|
||||||
unsafe {
|
unsafe {
|
||||||
radio_verify_config(device);
|
radio_verify_config(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read firmware image from the binary file.
|
/// Read firmware image from the binary file.
|
||||||
pub fn read_image(filename: &str) -> *const RadioDeviceT {
|
pub fn read_image(filename: &str) -> *const radio_device_t {
|
||||||
let filename = CString::new(filename.to_string()).unwrap();
|
let filename = CString::new(filename.to_string()).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
radio_read_image(filename.as_ptr())
|
radio_read_image(filename.as_ptr())
|
||||||
@ -84,7 +83,7 @@ pub fn read_image(filename: &str) -> *const RadioDeviceT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Save firmware image to the binary file.
|
/// Save firmware image to the binary file.
|
||||||
pub fn save_image(device: *const RadioDeviceT, filename: &str) {
|
pub fn save_image(device: *const radio_device_t, filename: &str) {
|
||||||
let filename = CString::new(filename.to_string()).unwrap();
|
let filename = CString::new(filename.to_string()).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
radio_save_image(device, filename.as_ptr())
|
radio_save_image(device, filename.as_ptr())
|
||||||
@ -92,7 +91,7 @@ pub fn save_image(device: *const RadioDeviceT, filename: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Read the configuration from text file, and modify the firmware.
|
/// Read the configuration from text file, and modify the firmware.
|
||||||
pub fn parse_config(device: *const RadioDeviceT, filename: &str) {
|
pub fn parse_config(device: *const radio_device_t, filename: &str) {
|
||||||
let filename = CString::new(filename.to_string()).unwrap();
|
let filename = CString::new(filename.to_string()).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
radio_parse_config(device, filename.as_ptr())
|
radio_parse_config(device, filename.as_ptr())
|
||||||
@ -100,7 +99,7 @@ pub fn parse_config(device: *const RadioDeviceT, filename: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Print full information about the device configuration.
|
/// Print full information about the device configuration.
|
||||||
pub fn print_config(device: *const RadioDeviceT, filename: &str) {
|
pub fn print_config(device: *const radio_device_t, filename: &str) {
|
||||||
let file = std::fs::File::create(filename).unwrap();
|
let file = std::fs::File::create(filename).unwrap();
|
||||||
let fd = file.as_raw_fd();
|
let fd = file.as_raw_fd();
|
||||||
let mode = CString::new("w").unwrap();
|
let mode = CString::new("w").unwrap();
|
||||||
@ -111,7 +110,7 @@ pub fn print_config(device: *const RadioDeviceT, filename: &str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_config_to_stdout(device: *const RadioDeviceT) {
|
pub fn print_config_to_stdout(device: *const radio_device_t) {
|
||||||
let mode = CString::new("w").unwrap();
|
let mode = CString::new("w").unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
let stdout = libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr());
|
let stdout = libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr());
|
||||||
@ -125,7 +124,7 @@ pub fn print_config_to_stdout(device: *const RadioDeviceT) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Print generic information about the device.
|
/// Print generic information about the device.
|
||||||
pub fn print_version(device: *const RadioDeviceT) {
|
pub fn print_version(device: *const radio_device_t) {
|
||||||
let mode = CString::new("w").unwrap();
|
let mode = CString::new("w").unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
radio_print_version(device, libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr()));
|
radio_print_version(device, libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr()));
|
||||||
@ -133,7 +132,7 @@ pub fn print_version(device: *const RadioDeviceT) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update CSV contacts database.
|
/// Update CSV contacts database.
|
||||||
pub fn write_csv(device: *const RadioDeviceT, filename: &str) {
|
pub fn write_csv(device: *const radio_device_t, filename: &str) {
|
||||||
let filename = CString::new(filename.to_string()).unwrap();
|
let filename = CString::new(filename.to_string()).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
radio_write_csv(device, filename.as_ptr());
|
radio_write_csv(device, filename.as_ptr());
|
||||||
|
Loading…
Reference in New Issue
Block a user