Skip to content

Commit

Permalink
Cleanup transmit cli a bit
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Young <[email protected]>
  • Loading branch information
seanyoung committed May 20, 2024
1 parent 5c84324 commit 2a84c14
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 45 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ cir transmit --keymap RM-Y173.lircd.conf --keycode KEY_CHANNELUP
```
Alternatively, you can send raw IR directly like so:
```bash
cir transmit '+9000 -4500 +560'
cir transmit --raw '+9000 -4500 +560'
```
You can also send files or linux kernel scancodes, using the same options like `ir-ctl`. This supports
mode2 files or raw IR files.
Expand Down
2 changes: 1 addition & 1 deletion TODO
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Necessary:
Nice to have:
- ir encode/send needs to read xml file
- cir decode irp should read IrpProtocols.xml
- cir transmit rawir -S sony15:12 -r 2 ??
- cir transmit -S sony15:12 -R 2 ??
- pcmak leading gap not decoded
- encoding toggle_bit_mask not used when popcount > 1
- compare against kernel encoder/decoder
Expand Down
45 changes: 31 additions & 14 deletions cir/src/bin/cir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,21 @@ fn parse_scankey(arg: &str) -> Result<(u64, String), String> {
}
}

fn parse_scancode(arg: &str) -> Result<(String, u64), String> {
if let Some((protocol, scancode)) = arg.split_once(':') {
let scancode = if let Some(hex) = scancode.strip_prefix("0x") {
u64::from_str_radix(hex, 16)
} else {
str::parse(scancode)
}
.map_err(|e| format!("{e}"))?;

Ok((protocol.to_owned(), scancode))
} else {
Err("missing `:` separator".into())
}
}

#[cfg(target_os = "linux")]
#[derive(Args)]
struct Keymap {
Expand Down Expand Up @@ -297,55 +312,57 @@ struct Transmit {
#[arg(long = "dry-run", short = 'n')]
dry_run: bool,

/// List the codes in the keymap
/// List the codes in keymap
#[arg(long = "list-codes", short = 'l', requires = "KEYMAP")]
list_codes: bool,

/// Read from rawir or mode2 file
#[arg(long = "file", short = 'f', name = "FILE", help_heading = "INPUT")]
files: Vec<OsString>,

/// Send scancode using linux kernel protocols
/// Send scancode using linux kernel protocol
#[arg(
long = "scancode",
short = 'S',
name = "SCANCODE",
value_parser = parse_scancode,
help_heading = "INPUT"
)]
scancodes: Vec<String>,
scancodes: Vec<(String, u64)>,

/// Set gap after each file
/// Trailing gap length if none present
#[arg(long = "gap", short = 'g', name = "GAP", help_heading = "INPUT")]
gaps: Vec<u32>,

/// Pronto Hex code
#[arg(long = "pronto", short = 'p', name = "PRONTO", help_heading = "INPUT")]
pronto: Vec<String>,

/// Raw IR text
#[arg(name = "RAWIR", help_heading = "INPUT")]
/// Transmit raw IR
#[arg(long = "raw", short = 'r', name = "RAWIR", help_heading = "INPUT")]
rawir: Vec<String>,

/// Number of IRP repeats to encode
/// Number of repeats to encode
#[arg(
long = "repeats",
short = 'r',
short = 'R',
value_parser = value_parser!(u64).range(0..99),
default_value_t = 0,
help_heading = "INPUT"
)]
repeats: u64,

/// Set input variable like KEY=VALUE
/// Set IRP parameter like KEY=VALUE
#[arg(
long = "argument",
short = 'a',
value_delimiter = ',',
help_heading = "INPUT"
help_heading = "INPUT",
name = "ARGUMENT"
)]
arguments: Vec<String>,

/// IRP Notation
/// Transmit using IRP Notation
#[arg(long = "irp", short = 'i', name = "IRP", help_heading = "INPUT")]
irp: Vec<String>,

Expand All @@ -357,7 +374,7 @@ struct Transmit {
#[arg(name = "REMOTE", long = "remote", short = 'm', help_heading = "INPUT")]
remote: Option<String>,

/// Code from keymap to send
/// Code from keymap to transmit
#[arg(name = "CODE", long = "keycode", short = 'K', help_heading = "INPUT")]
codes: Vec<String>,

Expand Down Expand Up @@ -399,7 +416,7 @@ impl Transmit {
arg!("CODE", String, Code);
arg!("IRP", String, Irp);
arg!("GAP", u32, Gap);
arg!("SCANCODE", String, Scancode);
arg!("SCANCODE", (String, u64), Scancode);

part.sort_by(|a, b| a.1.cmp(&b.1));

Expand All @@ -414,7 +431,7 @@ enum Transmitables {
Code(String),
Irp(String),
Gap(u32),
Scancode(String),
Scancode((String, u64)),
}

impl FromArgMatches for Commands {
Expand Down
40 changes: 11 additions & 29 deletions cir/src/bin/commands/transmit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use cir::{
};
use irp::{Irp, Message, Pronto, Vartable};
use log::{error, info, warn};
use std::{fs, path::Path, str::FromStr};
use std::{fs, path::Path};
use terminal_size::{terminal_size, Width};

pub fn transmit(transmit: &crate::Transmit) {
Expand Down Expand Up @@ -229,23 +229,15 @@ fn encode_args(transmit: &crate::Transmit) -> Message {
std::process::exit(2);
}
},
crate::Transmitables::Scancode(scancode) => {
if let Some((protocol, code)) = scancode.split_once(':') {
match encode_scancode(protocol, code) {
Ok(m) => {
part.push(Part::Raw(m));
}
Err(msg) => {
error!("{}", msg);
std::process::exit(2);
}
crate::Transmitables::Scancode((protocol, scancode)) => {
match encode_scancode(protocol, *scancode) {
Ok(m) => {
part.push(Part::Raw(m));
}
Err(msg) => {
error!("{}", msg);
std::process::exit(2);
}
} else {
error!(
"{} is not a valid protocol, should be protocol:scancode",
scancode
);
std::process::exit(2);
}
}
crate::Transmitables::Gap(gap) => {
Expand Down Expand Up @@ -473,17 +465,7 @@ fn list_lircd_remotes(filename: &Path, remotes: &[lircd_conf::Remote], needle: O
}
}

fn encode_scancode(protocol: &str, code: &str) -> Result<Message, String> {
let mut scancode = if let Ok(code) = if let Some(hex) = code.strip_prefix("0x") {
u64::from_str_radix(hex, 16)
} else {
u64::from_str(code)
} {
code
} else {
return Err(format!("invalid scancode {code}"));
};

fn encode_scancode(protocol: &str, mut scancode: u64) -> Result<Message, String> {
let Some(linux) = LinuxProtocol::find_like(protocol) else {
return Err(format!("protocol {protocol} is not known"));
};
Expand All @@ -495,7 +477,7 @@ fn encode_scancode(protocol: &str, code: &str) -> Result<Message, String> {
let masked = scancode & linux.scancode_mask as u64;

if masked != scancode {
warn!("error: scancode {scancode:#x} masked to {masked:#x}");
warn!("scancode {scancode:#x} masked to {masked:#x}");
scancode = masked;
}

Expand Down
3 changes: 3 additions & 0 deletions cir/tests/encode_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ fn encode_rawir_test() {
.args([
"transmit",
"--dry-run",
"--raw",
r#"1000
200
1000"#,
Expand Down Expand Up @@ -127,9 +128,11 @@ fn encode_rawir_test() {
"--dry-run",
"-f",
"../testdata/rawir/mode2",
"-r",
"345",
"-g",
"30000",
"-r",
"+123 40 124",
"-g",
"40000",
Expand Down

0 comments on commit 2a84c14

Please sign in to comment.