1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use std::env;

use j1939::Id;

fn usage() {
    println!("Usage: j1939decode <input>");
    println!();
    println!("Options:");
    println!("  <input>     29-bit CAN ID in hexadecimal format (0x18EAFF00)");
}

fn main() {
    let input = env::args().nth(1);

    if input.is_none() {
        usage();
        return;
    }

    let id_str = input.unwrap();
    if !id_str.starts_with("0x") {
        usage();
        return;
    }

    let id_raw = u32::from_str_radix(id_str.trim_start_matches("0x"), 16).expect("Invalid ID");

    let id = Id::new(id_raw);

    println!("ID");
    println!(" Hex: 0x{:X?}", id.as_raw());
    println!(" Dec: {}", id.as_raw());
    println!(" Bin: {:029b}", id.as_raw());
    println!("Priority");
    println!(" Hex: 0x{:X?}", id.priority());
    println!(" Dec: {}", id.priority());
    println!(" Bin: {:03b}", id.priority());
    println!("Data Page (DP): {}", id.dp());
    println!("Parameter Group Number (PGN): {:?}", id.pgn());
    println!(" Hex: 0x{:X?}", id.pgn_raw());
    println!(" Dec: {}", id.pgn_raw());
    println!(" Bin: {:024b}", id.pgn_raw());
    println!("PDU Type: {:?}", id.pf());
    println!("Broadcast: {}", id.is_broadcast());

    if let Some(ge) = id.group_extension() {
        println!("Group Extension (GE)/PDU Specific (PS)");
        println!(" Hex: 0x{:X?}", ge);
        println!(" Dec: {}", ge);
        println!(" Bin: {:08b}", ge);
    }

    if let Some(da) = id.destination_address() {
        println!("Destination Address (DA)");
        println!(" Hex: 0x{:X?}", da);
        println!(" Dec: {}", da);
        println!(" Bin: {:08b}", da);
    }

    println!("Source Address (SA)");
    println!(" Hex: 0x{:X?}", id.sa());
    println!(" Dec: {}", id.sa());
    println!(" Bin: {:08b}", id.sa());
}