Skip to content

Commit

Permalink
Use IrpProtocols.xml
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Young <[email protected]>
  • Loading branch information
seanyoung committed May 21, 2024
1 parent 809a378 commit 8b06843
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 15 deletions.
6 changes: 3 additions & 3 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ Necessary:
correct protocol numbers

Nice to have:
- ir encode/send needs to read xml file
- cir decode irp should read IrpProtocols.xml
- cir decode irp should try all protocols if nothing specified
- cir decode should allow multiple IRPs/keymaps
- pcmak leading gap not decoded
- encoding toggle_bit_mask not used when popcount > 1
- compare against kernel encoder/decoder

Needed for release:
- Need ir-ctl and ir-keytable command line parsing
- man pages
- man pages
- rc_mapping() kfunc
- localization of cli messages
- shell completion
Expand Down
26 changes: 23 additions & 3 deletions cir/src/bin/cir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ use clap::{
error::{Error, ErrorKind},
value_parser, ArgAction, ArgMatches, Args, Command, FromArgMatches, Parser, Subcommand,
};
use irp::Protocol;
use log::{Level, LevelFilter, Metadata, Record};
use std::{ffi::OsString, path::PathBuf};
use std::{
ffi::OsString,
io,
path::{Path, PathBuf},
sync::OnceLock,
};

mod commands;

Expand All @@ -24,6 +30,14 @@ struct App {
#[arg(long, short, global = true, conflicts_with = "verbose")]
quiet: bool,

/// Location of IrpProtocols.xml
#[arg(
long = "irp-protocols",
global = true,
default_value = "/usr/share/rc_keymaps/IrpProtocols.xml"
)]
irp_protocols: PathBuf,

#[command(subcommand)]
command: Commands,
}
Expand Down Expand Up @@ -573,7 +587,7 @@ fn main() {
match &args.command {
Commands::Decode(decode) => {
if let Some(irp) = &decode.irp {
commands::decode::decode_irp(decode, irp)
commands::decode::decode_irp(&args.irp_protocols, decode, irp)
} else {
let keymap = decode.keymap.as_ref().unwrap();

Expand All @@ -584,7 +598,7 @@ fn main() {
}
}
}
Commands::Transmit(args) => commands::transmit::transmit(args),
Commands::Transmit(tx) => commands::transmit::transmit(&args, tx),
#[cfg(target_os = "linux")]
Commands::List(args) => commands::list::list(args),
#[cfg(target_os = "linux")]
Expand All @@ -594,6 +608,12 @@ fn main() {
}
}

static IRP_PROTOCOLS: OnceLock<io::Result<Vec<Protocol>>> = OnceLock::new();

fn get_irp_protocols(path: &Path) -> &'static io::Result<Vec<Protocol>> {
IRP_PROTOCOLS.get_or_init(|| Protocol::parse(path))
}

static CLI_LOGGER: CliLogger = CliLogger;

struct CliLogger;
Expand Down
30 changes: 26 additions & 4 deletions cir/src/bin/commands/decode.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[cfg(target_os = "linux")]
use super::keymap::{find_devices, Purpose};
use crate::get_irp_protocols;
#[cfg(target_os = "linux")]
use cir::lirc::Lirc;
use cir::{keymap::Keymap, lircd_conf::parse};
Expand All @@ -11,17 +12,38 @@ use std::{
path::{Path, PathBuf},
};

pub fn decode_irp(decode: &crate::Decode, irp_str: &String) {
pub fn decode_irp(irp_protocols: &Path, decode: &crate::Decode, irp_notation: &String) {
let mut protocols = &Vec::new();

match get_irp_protocols(irp_protocols) {
Ok(res) => {
protocols = res;
}
Err(e) => {
log::error!("{}: {e}", irp_protocols.display());
}
};

let irp_notation = match protocols
.iter()
.find(|e| e.decodable && (&e.name == irp_notation || e.alt_name.contains(irp_notation)))
{
Some(e) => &e.irp,
None => irp_notation,
};

log::debug!("decoding IRP: {irp_notation}");

#[allow(unused_mut)]
let mut abs_tolerance = decode.options.aeps.unwrap_or(100);
let rel_tolerance = decode.options.eps.unwrap_or(3);
#[allow(unused_mut)]
let mut max_gap = 100000;

let irp = match Irp::parse(irp_str) {
let irp = match Irp::parse(irp_notation) {
Ok(m) => m,
Err(s) => {
eprintln!("unable to parse irp ‘{irp_str}’: {s}");
eprintln!("unable to parse irp ‘{irp_notation}’: {s}");
std::process::exit(2);
}
};
Expand Down Expand Up @@ -50,7 +72,7 @@ pub fn decode_irp(decode: &crate::Decode, irp_str: &String) {
let dfa = match irp.compile(&options) {
Ok(dfa) => dfa,
Err(s) => {
eprintln!("unable to compile irp ‘{irp_str}’: {s}");
eprintln!("unable to compile irp ‘{irp_notation}’: {s}");
std::process::exit(2);
}
};
Expand Down
28 changes: 25 additions & 3 deletions cir/src/bin/commands/transmit.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::get_irp_protocols;

#[cfg(target_os = "linux")]
use super::keymap::{open_lirc, Purpose};
use cir::{
Expand All @@ -9,8 +11,8 @@ use log::{error, info, warn};
use std::{fs, path::Path};
use terminal_size::{terminal_size, Width};

pub fn transmit(transmit: &crate::Transmit) {
let message = encode_args(transmit);
pub fn transmit(args: &crate::App, transmit: &crate::Transmit) {
let message = encode_args(&args.irp_protocols, transmit);

if let Some(carrier) = &message.carrier {
if *carrier == 0 {
Expand Down Expand Up @@ -116,7 +118,7 @@ pub fn transmit(transmit: &crate::Transmit) {
}
}

fn encode_args(args: &crate::Transmit) -> Message {
fn encode_args(irp_protocols: &Path, args: &crate::Transmit) -> Message {
let mut vars = irp::Vartable::new();

for field in &args.arguments {
Expand Down Expand Up @@ -257,6 +259,26 @@ fn encode_args(args: &crate::Transmit) -> Message {
part.push(Part::Raw(m));
}
crate::Transmitables::Irp(irp_notation) => {
let mut protocols = &Vec::new();

match get_irp_protocols(irp_protocols) {
Ok(res) => {
protocols = res;
}
Err(e) => {
log::error!("{}: {e}", irp_protocols.display());
}
};

let irp_notation = match protocols.iter().find(|e| {
!e.decode_only && (&e.name == irp_notation || e.alt_name.contains(irp_notation))
}) {
Some(e) => &e.irp,
None => irp_notation,
};

log::debug!("transmit IRP: {irp_notation}");

let irp = match Irp::parse(irp_notation) {
Ok(m) => m,
Err(s) => {
Expand Down
28 changes: 28 additions & 0 deletions cir/tests/decode_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,31 @@ debug: scancode 0x100060
"#
);
}

#[test]
fn irp() {
let mut cmd = Command::cargo_bin("cir").unwrap();

let assert = cmd
.args([
"decode",
"-i",
"Blaupunkt",
"--irp-protocols=../irp/tests/IrpTransmogrifier/src/main/resources/IrpProtocols.xml",
"--raw=+512 -2560 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -23040 +512 -2560 +512 -1024 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +1024 -1024 +512 -512 +512 -120832 +512 -2560 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -23040",
])
.assert();

let output = assert.get_output();

let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);

assert_eq!(stderr, "info: decoding: +512 -2560 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -23040 +512 -2560 +512 -1024 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +1024 -1024 +512 -512 +512 -120832 +512 -2560 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -23040\n");

assert_eq!(
stdout,
r#"decoded: down D=1, F=0
"#
);
}
30 changes: 30 additions & 0 deletions cir/tests/encode_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,36 @@ info: rawir: +2664 -888 +444 -444 +444 -444 +444 -888 +444 -888 +888 -444 +444 -
);
}

#[test]
fn encode_irp_test() {
let mut cmd = Command::cargo_bin("cir").unwrap();

let assert = cmd
.args([
"transmit",
"--dry-run",
"--irp=Blaupunkt",
"--irp-protocols",
"../irp/tests/IrpTransmogrifier/src/main/resources/IrpProtocols.xml",
"-aF=0,D=1",
])
.assert();

let output = assert.get_output();

let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);

assert_eq!(stdout, "");

assert_eq!(
stderr,
r#"info: carrier: 30300Hz
info: rawir: +512 -2560 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -23040 +512 -2560 +512 -1024 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +1024 -1024 +512 -512 +512 -120832 +512 -2560 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -512 +512 -23040
"#
);
}

#[test]
fn encode_lircd_aiwa_test() {
let mut cmd = Command::cargo_bin("cir").unwrap();
Expand Down
4 changes: 2 additions & 2 deletions irp/src/protocols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub struct Protocol {
pub minimum_leadout: u32,
pub decode_only: bool,
pub decodable: bool,
pub reject_repeatess: bool,
pub reject_repeatless: bool,
}

enum Element {
Expand Down Expand Up @@ -122,7 +122,7 @@ impl Protocol {
protocol.decode_only = bool::from_str(&data).unwrap();
}
Element::RejectRepeatLess => {
protocol.reject_repeatess = bool::from_str(&data).unwrap();
protocol.reject_repeatless = bool::from_str(&data).unwrap();
}
Element::AbsoluteTolerance => {
protocol.absolute_tolerance = u32::from_str(&data).unwrap();
Expand Down

0 comments on commit 8b06843

Please sign in to comment.