Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 38 additions & 19 deletions src/cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ use crate::link::Protocol;

/// CAT Protocol opcodes
enum Opcode {
GET = 0x47, // G
SET = 0x53, // S
GET = 0x47, // G
SET = 0x53, // S
DATA = 0x44, // D
ACK = 0x41, // A
ACK = 0x41, // A
}

impl TryFrom<u8> for Opcode {
Expand All @@ -33,9 +33,9 @@ impl TryFrom<u8> for Opcode {
/// CAT Protocol IDs
#[derive(Copy, Clone)]
enum ID {
INFO = 0x494E, // IN
FREQRX = 0x5246, // RF
FREQTX = 0x5446, // TF
INFO = 0x494E, // IN
FREQRX = 0x5246, // RF
FREQTX = 0x5446, // TF
FILETRANSFER = 0x4654, // FT
}

Expand All @@ -46,10 +46,15 @@ const HZ_IN_MHZ: f64 = 1000000.0;
fn get(id: ID) -> Vec<u8> {
let mut link = Link::acquire();

let cmd: Vec<u8> = vec![Opcode::GET as u8,
((id as u16 >> 8) & 0xff) as u8,
(id as u16 & 0xff) as u8];
let frame = Frame{proto: Protocol::CAT, data: cmd};
let cmd: Vec<u8> = vec![
Opcode::GET as u8,
((id as u16 >> 8) & 0xff) as u8,
(id as u16 & 0xff) as u8,
];
let frame = Frame {
proto: Protocol::CAT,
data: cmd,
};
link.send(frame);

// Loop until we get a message of the right protocol
Expand All @@ -66,9 +71,15 @@ fn get(id: ID) -> Vec<u8> {
match opcode {
Opcode::ACK => match data[1] {
0 => (),
status => println!("Error in GET request: {:?}", Errno::try_from(status).unwrap()),
status => println!(
"Error in GET request: {:?}",
Errno::try_from(status).unwrap()
),
}, // Error?
Opcode::DATA => { data.remove(0); () }, // Correct response!
Opcode::DATA => {
data.remove(0);
()
} // Correct response!
_ => panic!("Error while parsing GET response"),
};
link.release();
Expand All @@ -79,11 +90,16 @@ fn get(id: ID) -> Vec<u8> {
fn set(id: ID, data: &[u8]) {
let mut link = Link::acquire();

let mut cmd: Vec<u8> = vec![Opcode::SET as u8,
((id as u16 >> 8) & 0xff) as u8,
(id as u16 & 0xff) as u8];
let mut cmd: Vec<u8> = vec![
Opcode::SET as u8,
((id as u16 >> 8) & 0xff) as u8,
(id as u16 & 0xff) as u8,
];
cmd.extend(data);
let frame = Frame{proto: Protocol::CAT, data: cmd};
let frame = Frame {
proto: Protocol::CAT,
data: cmd,
};
link.send(frame);

let mut frame: Frame;
Expand All @@ -100,7 +116,10 @@ fn set(id: ID, data: &[u8]) {
match opcode {
Opcode::ACK => match data[1] {
0 => (),
status => println!("Error in SET request: {:?}", Errno::try_from(status).unwrap()),
status => println!(
"Error in SET request: {:?}",
Errno::try_from(status).unwrap()
),
}, // Error?
_ => panic!("Error while parsing SET response"),
};
Expand Down Expand Up @@ -130,15 +149,15 @@ pub fn freq(data: Option<String>, is_tx: bool) {
true => println!("Tx: {freq} MHz"),
false => println!("Rx: {freq} MHz"),
};
},
}
// SET
Some(data) => {
let freq: f64 = data.parse::<f64>().unwrap();
let freq: u32 = (freq * HZ_IN_MHZ) as u32;
let mut data: [u8; 4] = [0, 0, 0, 0];
LittleEndian::write_u32(&mut data, freq);
set(id, &data);
},
}
};
}

Expand Down
42 changes: 31 additions & 11 deletions src/dat.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//! This module handles the Data Transfer Protocol portion of rtxlink

use text_colorizer::*;
use std::fs::{File, read};
use std::fs::{read, File};
use std::io::Write;
use std::io::{Error, ErrorKind};
use std::sync::mpsc::Sender;
use text_colorizer::*;

use crate::link::Errno;
use crate::link::Frame;
Expand All @@ -16,7 +16,10 @@ const DAT_PAYLOAD_SIZE: usize = DAT_FRAME_SIZE - 2;

/// This function sends an ACK to signal the correct reception of a DAT frame
pub fn send_ack(link: &mut Link) {
let frame = Frame{proto: Protocol::DAT, data: vec![0x06]};
let frame = Frame {
proto: Protocol::DAT,
data: vec![0x06],
};
link.send(frame);
}

Expand All @@ -36,13 +39,21 @@ pub fn wait_ack() {
let ack = frame.data[0];
match ack {
0x06 => (),
status => println!("{}: {:?}", "Error".bold().red(), Errno::try_from(status).unwrap()),
status => println!(
"{}: {:?}",
"Error".bold().red(),
Errno::try_from(status).unwrap()
),
}
link.release();
}

/// This function receives data using the DAT protocol
pub fn receive(file_name: &str, size: usize, progress: Option<&Sender<(usize, usize)>>) -> std::io::Result<()> {
pub fn receive(
file_name: &str,
size: usize,
progress: Option<&Sender<(usize, usize)>>,
) -> std::io::Result<()> {
let mut receive_size: usize = 0;
let mut prev_block: i16 = -1;
let mut file = File::create(&file_name)?;
Expand All @@ -61,9 +72,11 @@ pub fn receive(file_name: &str, size: usize, progress: Option<&Sender<(usize, us
// Check sanity of block number and its inverse
let block_number = frame.data[0];
let inv_block_number = frame.data[1];
if (block_number + inv_block_number != 255) ||
(block_number != (prev_block + 1) as u8) {
return Err(Error::new(ErrorKind::Other, "Error in DAT protocol receive: bad block indexing!"));
if (block_number + inv_block_number != 255) || (block_number != (prev_block + 1) as u8) {
return Err(Error::new(
ErrorKind::Other,
"Error in DAT protocol receive: bad block indexing!",
));
}
prev_block = block_number as i16;
receive_size += frame.data.len() - 2;
Expand Down Expand Up @@ -95,13 +108,20 @@ pub fn send(file_name: &str, size: usize, progress: Option<&Sender<(usize, usize
chunk[0] = i as u8;
chunk[1] = 255 - i as u8;
let remaining_data: usize = size - (i - 1) * DAT_PAYLOAD_SIZE;
let chunk_size: usize = if remaining_data < DAT_PAYLOAD_SIZE {remaining_data} else {DAT_PAYLOAD_SIZE};
let start_offset = (i-1) * DAT_PAYLOAD_SIZE;
let chunk_size: usize = if remaining_data < DAT_PAYLOAD_SIZE {
remaining_data
} else {
DAT_PAYLOAD_SIZE
};
let start_offset = (i - 1) * DAT_PAYLOAD_SIZE;
let end_offset = start_offset + chunk_size;
chunk[2..chunk_size + 2].copy_from_slice(&file_content[start_offset..end_offset]);
chunk.resize(chunk_size, 0);
let mut link = Link::acquire();
let frame = Frame{proto: Protocol::DAT, data: chunk};
let frame = Frame {
proto: Protocol::DAT,
data: chunk,
};
link.send(frame);
link.release();
send_size += chunk_size;
Expand Down
20 changes: 12 additions & 8 deletions src/flow.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use url::Url;
use std::sync::mpsc::Sender;
use std::env::current_dir;
use std::sync::mpsc::Sender;
use url::Url;

use crate::cat;
use crate::fmp;
Expand All @@ -23,8 +23,7 @@ pub fn backup(dest_path: Option<String>, progress: Option<&Sender<(usize, usize)
file_name.push_str(&radio_name);
file_name.push_str("_");
file_name.push_str(&mem.to_string());
file_name.push_str(&chrono::offset::Local::now().format("_%d%m%Y")
.to_string());
file_name.push_str(&chrono::offset::Local::now().format("_%d%m%Y").to_string());
file_name.push_str(".bin");
match fmp::dump(i, &mem, &file_name, progress) {
Err(why) => panic!("Error while storing backup on {}: {}", file_name, why),
Expand All @@ -33,11 +32,16 @@ pub fn backup(dest_path: Option<String>, progress: Option<&Sender<(usize, usize)
}
}

pub fn restore(mem_index: Option<String>, src_path: Option<String>, progress: Option<&Sender<(usize, usize)>>) {
pub fn restore(
mem_index: Option<String>,
src_path: Option<String>,
progress: Option<&Sender<(usize, usize)>>,
) {
// Parse parameters
let mem_index = mem_index.expect("Error: memory index not found!")
.parse::<usize>()
.expect("Error: invalid memory index!");
let mem_index = mem_index
.expect("Error: memory index not found!")
.parse::<usize>()
.expect("Error: invalid memory index!");
let src_path = src_path.expect("Error: backup file not found!");
let mem_list = fmp::meminfo();
if mem_index > mem_list.len() {
Expand Down
Loading