first commit
This commit is contained in:
commit
547910b880
4 changed files with 185 additions and 0 deletions
22
.gitignore
vendored
Normal file
22
.gitignore
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
/target
|
||||||
|
**/*.rs.bk
|
||||||
|
Cargo.lock
|
||||||
|
**/*.rs.bk
|
||||||
|
/.idea
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
.vscode/
|
||||||
|
*.sublime-workspace
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
.env
|
||||||
|
docker-compose.override.yml
|
||||||
|
*.env
|
||||||
|
*.env.template
|
||||||
|
*.env.sample
|
17
Cargo.toml
Normal file
17
Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
[package]
|
||||||
|
name = "at-sender"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serialport = { version = "4.0", default-features = false }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = { version = "1.0", features = ["alloc"] }
|
||||||
|
clap = { version = "3.0", features = ["std"] }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = 'z'
|
||||||
|
lto = true
|
||||||
|
codegen-units = 1
|
||||||
|
panic = 'abort'
|
||||||
|
strip = true
|
51
README.md
Normal file
51
README.md
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# AT Sender
|
||||||
|
|
||||||
|
The `at_sender` program is a simple command-line tool written in Rust, designed to send AT commands to 4G/5G modems on embedded devices. It is intended to be used as a diagnostic tool for testing the modem's AT command interface.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Rust 1.41 or later
|
||||||
|
- Access to a serial device
|
||||||
|
- Linux operating system (for the provided build commands)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Clone the repository and navigate into the project directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.difuse.io/Difuse/at-sender.git
|
||||||
|
cd at-sender
|
||||||
|
```
|
||||||
|
|
||||||
|
For easy native builds, use the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo build --release
|
||||||
|
```
|
||||||
|
|
||||||
|
Compiling for other targets is also possible, but requires additional setup (You are on your own for this one), here's a great docker container that you can use to build for `aarch64-musl`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -v $(pwd):/home/rust/src messense/rust-musl-cross:aarch64-musl cargo build --release
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
./at_sender --port /dev/ttyUSB2 --baud 115200 --data 8 --stop 1 --cmd "AT" --buf 32
|
||||||
|
```
|
||||||
|
|
||||||
|
### Flags
|
||||||
|
|
||||||
|
* `--port`: The serial port to connect to (default "/dev/ttyUSB2")
|
||||||
|
* `--baud`: The baud rate (default 115200)
|
||||||
|
* `--data`: The number of data bits (default 8)
|
||||||
|
* `--stop`: The number of stop bits (default 1)
|
||||||
|
* `--cmd`: The command to send to the serial device (default "AT")
|
||||||
|
* `--buf`: The buffer size for reading from the serial device (default 4)
|
||||||
|
|
||||||
|
The flags can be specified in any order. If a flag is omitted, the default value will be used.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
GPL-3.0
|
95
src/main.rs
Normal file
95
src/main.rs
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
use clap::{App, Arg};
|
||||||
|
use serde::{Serialize};
|
||||||
|
use serialport::{DataBits, FlowControl, Parity, StopBits};
|
||||||
|
use std::{io::Write, thread, time::Duration};
|
||||||
|
use serde_json;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Result {
|
||||||
|
data: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let matches = App::new("Serial Port Communication with AT commands")
|
||||||
|
.version("0.1.0")
|
||||||
|
.author("Hayzam <hayzam@difuse.io>")
|
||||||
|
.about("Sends AT commands to a serial device and reads the response.")
|
||||||
|
.arg(Arg::with_name("port")
|
||||||
|
.long("port")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("/dev/ttyUSB2")
|
||||||
|
.help("The serial port to connect to"))
|
||||||
|
.arg(Arg::with_name("baud")
|
||||||
|
.long("baud")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("115200")
|
||||||
|
.help("The baud rate"))
|
||||||
|
.arg(Arg::with_name("data")
|
||||||
|
.long("data")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("8")
|
||||||
|
.help("The number of data bits"))
|
||||||
|
.arg(Arg::with_name("stop")
|
||||||
|
.long("stop")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("1")
|
||||||
|
.help("The number of stop bits"))
|
||||||
|
.arg(Arg::with_name("cmd")
|
||||||
|
.long("cmd")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("AT")
|
||||||
|
.help("The command to send to the serial device"))
|
||||||
|
.arg(Arg::with_name("buf")
|
||||||
|
.long("buf")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("4")
|
||||||
|
.help("The buffer size for reading from the serial device"))
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
let port_name = matches.value_of("port").unwrap();
|
||||||
|
let baud_rate = matches.value_of("baud").unwrap().parse::<u32>().expect("Invalid baud rate format");
|
||||||
|
|
||||||
|
let data_bits = match matches.value_of("data").unwrap() {
|
||||||
|
"8" => DataBits::Eight,
|
||||||
|
"7" => DataBits::Seven,
|
||||||
|
_ => panic!("Unsupported data bits"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let stop_bits = match matches.value_of("stop").unwrap() {
|
||||||
|
"1" => StopBits::One,
|
||||||
|
"2" => StopBits::Two,
|
||||||
|
_ => panic!("Unsupported stop bits"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let command = matches.value_of("cmd").unwrap();
|
||||||
|
|
||||||
|
let buf_size: usize = matches.value_of("buf").unwrap_or("4").parse().unwrap_or_else(|err| {
|
||||||
|
eprintln!("Error parsing buffer size: {}", err);
|
||||||
|
std::process::exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
let port = serialport::new(port_name, baud_rate)
|
||||||
|
.data_bits(data_bits)
|
||||||
|
.flow_control(FlowControl::None)
|
||||||
|
.parity(Parity::None)
|
||||||
|
.stop_bits(stop_bits)
|
||||||
|
.timeout(Duration::from_secs(1))
|
||||||
|
.open()
|
||||||
|
.expect("Failed to open port");
|
||||||
|
|
||||||
|
let mut port = Box::new(port);
|
||||||
|
|
||||||
|
port.write_all(command.as_bytes()).expect("Failed to write to port");
|
||||||
|
port.write_all(b"\r").expect("Failed to write CR to port");
|
||||||
|
|
||||||
|
thread::sleep(Duration::from_millis(1000));
|
||||||
|
|
||||||
|
let mut buf = vec![0u8; buf_size];
|
||||||
|
let n = port.read(&mut buf).expect("Failed to read from port");
|
||||||
|
let result = Result {
|
||||||
|
data: String::from_utf8_lossy(&buf[..n]).into_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let json_output = serde_json::to_string(&result).expect("Failed to serialize result");
|
||||||
|
println!("{}", json_output);
|
||||||
|
}
|
Loading…
Reference in a new issue