Skip to content

Commit

Permalink
Add Command Line Args, automatic dependency updates (#45)
Browse files Browse the repository at this point in the history
* add cmdline parser

* add dependabot
  • Loading branch information
jr1221 authored Aug 12, 2024
1 parent c2fb31c commit 3549c73
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 32 deletions.
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
120 changes: 120 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ paho-mqtt = "0.12.5"
protobuf-codegen = "3.3.0"
protobuf = "3.3.0"
bitstream-io = "2.5.0"
clap = { version = "4.5.15", features = ["derive", "env"] }


[build-dependencies]
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Calypso
Custom CAN decoder to translate CAN messages to MQTT protobuf encoded packets with low latency and a YAML configuration structure.

Usage: run `-h` to see the full usage options and defaults.

### Develop setup
#### Go to Settings in VSCode
Expand Down Expand Up @@ -30,7 +31,7 @@ Process for testing:
- `sudo ip link add dev vcan0 type vcan`
- `sudo ip link set dev vcan0 up`

run ```cargo run localhost:1883 vcan0```
run ```cargo run -- -u localhost:1883 -c vcan0```

To send a can message:
- `cansend vcan0 <ID_IN_HEX>#<PAYLOAD_IN_HEX>`
Expand Down
64 changes: 33 additions & 31 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::{
collections::HashMap,
env, process,
sync::{Arc, RwLock},
thread::{self, JoinHandle},
time::Duration,
Expand All @@ -11,11 +10,39 @@ use calypso::{
encodable_message::EncodableMessage, encode_master_mapping::ENCODABLE_KEY_LIST,
mqtt::MqttClient, serverdata,
};
use clap::Parser;
use protobuf::Message;
use socketcan::{CanFrame, CanSocket, EmbeddedFrame, Id, Socket};

const ENCODER_MAP_SUB: &str = "Calypso/Bidir/Command/#";

/// Calypso command line arguments
#[derive(Parser, Debug)]
#[command(version)]
struct CalypsoArgs {
/// Whether to enable CAN message encoding
#[arg(short = 'e', long, env = "CALYPSO_CAN_ENCODE")]
encode: bool,

/// The host url of the siren, including port and excluding protocol prefix
#[arg(
short = 'u',
long,
env = "CALYPSO_SIREN_HOST_URL",
default_value = "localhost:1883"
)]
siren_host_url: String,

/// The SocketCAN interface port
#[arg(
short = 'c',
long,
env = "CALYPSO_SOCKETCAN_IFACE",
default_value = "vcan0"
)]
socketcan_iface: String,
}

/**
* Reads the can socket and publishes the data to the given client.
*/
Expand Down Expand Up @@ -173,48 +200,23 @@ fn send_out(
})
}

/**
* Parses the command line arguments.
*/
fn parse_args() -> (String, String, bool) {
let args: Vec<String> = env::args().collect();
println!("{:?}", args);
if args.len() < 3 {
println!("Not enough arguments!");
println!("Siren (MQTT) URL and can interface are required");
process::exit(1);
}
let path = &args[1];
let can_interface = &args[2];
let encode_en = args.len() >= 4 && args[3] == "encode_en";

println!("Siren URL: {}", path);
println!("Can interface: {}", can_interface);

(String::from(path), String::from(can_interface), encode_en)
}

/**
* Main Function
* Configures the can network, retrieves the client based on the command line arguments,
* connects the client and then reads the can socket from specified interface.
*
* Args:
* 1 -> IP address:port of Siren mqtt server (ex. localhost:1883)
* 2 -> Socketcan interface name (ex. vcan0)
* 3 -> encode_en or blank, whether to enable encoding
*/
fn main() {
let (path, can_interface, encoding) = parse_args();
let can_handle = read_can(&path, &can_interface);
let cli = CalypsoArgs::parse();
let can_handle = read_can(&cli.siren_host_url, &cli.socketcan_iface);

// use a arc for mutlithread, and a rwlock to enforce one writer
if encoding {
if cli.encode {
let send_map: Arc<RwLock<HashMap<u32, EncodeData>>> = Arc::new(RwLock::new(HashMap::new()));

let siren_handle = read_siren(&path, Arc::clone(&send_map));
let siren_handle = read_siren(&cli.siren_host_url, Arc::clone(&send_map));

let send_handle = send_out(&can_interface, Arc::clone(&send_map));
let send_handle = send_out(&cli.socketcan_iface, Arc::clone(&send_map));

siren_handle.join().expect("Encoder failed with ");
println!("Encoder ended");
Expand Down

0 comments on commit 3549c73

Please sign in to comment.