Skip to content

meshtastic/rust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Meshtastic.rs

Important

📢 Meshtastic Rust needs a new platform owner / maintainer 📢

More details are available in Issue #25.

Overview

Meshtastic.rs is a crate that allows you to interact with Meshtastic devices in Rust. This crate is designed to be used on a desktop environment, and currently supports connecting to radios via USB serial and TCP.

This crate is designed to be used within the tokio asynchronous runtime.

Crates.io Documentation License

Installation

You can add this crate to your project using the following command:

cargo add meshtastic

Alternatively, you can clone this repository to your own working directory:

git clone https://github.com/meshtastic/rust.git

Recursively clone our Git submodules by running:

git submodule update --init

Usage

This crate provides basic TCP and serial connection examples within the /examples directory. You can run these examples using the following commands:

cargo run --example basic_tcp
cargo run --example basic_serial

TCP Example

This example requires a Meshtastic with an exposed IP port, or a simulated radio via the Meshtastic Docker instance (see here).

/// This example connects to a TCP port on the radio, and prints out all received packets.
/// This can be used with a simulated radio via the Meshtastic Docker firmware image.
/// https://meshtastic.org/docs/software/linux-native#usage-with-docker

use std::io::{self, BufRead};

use meshtastic::api::StreamApi;
use meshtastic::utils;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let stream_api = StreamApi::new();

    println!("Enter the address of a TCP port to connect to, in the form \"IP:PORT\":");

    let stdin = io::stdin();
    let entered_address = stdin
        .lock()
        .lines()
        .next()
        .expect("Failed to find next line")
        .expect("Could not read next line");

    let tcp_stream = utils::stream::build_tcp_stream(entered_address).await?;
    let (mut decoded_listener, stream_api) = stream_api.connect(tcp_stream).await;

    let config_id = utils::generate_rand_id();
    let stream_api = stream_api.configure(config_id).await?;

    // This loop can be broken with ctrl+c, or by unpowering the radio.
    while let Some(decoded) = decoded_listener.recv().await {
        println!("Received: {:?}", decoded);
    }

    // Note that in this specific example, this will only be called when
    // the radio is disconnected, as the above loop will never exit.
    // Typically you would allow the user to manually kill the loop,
    // for example with tokio::select!.
    let _stream_api = stream_api.disconnect().await?;

    Ok(())
}

Serial Example

This example requires a powered and flashed Meshtastic radio connected to the host machine via a USB serial port.

/// This example connects to a radio via serial, and prints out all received packets.
/// This example requires a powered and flashed Meshtastic radio.
/// https://meshtastic.org/docs/supported-hardware

use std::io::{self, BufRead};

use meshtastic::api::StreamApi;
use meshtastic::utils;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let stream_api = StreamApi::new();

    let available_ports = utils::stream::available_serial_ports()?;
    println!("Available ports: {:?}", available_ports);
    println!("Enter the name of a port to connect to:");

    let stdin = io::stdin();
    let entered_port = stdin
        .lock()
        .lines()
        .next()
        .expect("Failed to find next line")
        .expect("Could not read next line");

    let serial_stream = utils::stream::build_serial_stream(entered_port, None, None, None)?;
    let (mut decoded_listener, stream_api) = stream_api.connect(serial_stream).await;

    let config_id = utils::generate_rand_id();
    let stream_api = stream_api.configure(config_id).await?;

    // This loop can be broken with ctrl+c, or by disconnecting
    // the attached serial port.
    while let Some(decoded) = decoded_listener.recv().await {
        println!("Received: {:?}", decoded);
    }

    // Note that in this specific example, this will only be called when
    // the radio is disconnected, as the above loop will never exit.
    // Typically you would allow the user to manually kill the loop,
    // for example with tokio::select!.
    let _stream_api = stream_api.disconnect().await?;

    Ok(())
}

Bluetooth Low-energy (BLE) Example

This example requires a powered and flashed Meshtastic radio with BLE enabled. You need to pair it first using your operating system utilities. PIN might be needed.

Note

You need bluetooth-le feature enabled for Bluetooth low energy support.

/// This example connects via Bluetooth LE to the radio, and prints out all received packets.
extern crate meshtastic;

use std::io::{self, BufRead};
use std::time::Duration;

use meshtastic::api::StreamApi;
use meshtastic::utils;
use meshtastic::utils::stream::BleId;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let stream_api = StreamApi::new();

    println!("Enter the short name of a BLE device to connect to:");

    let stdin = io::stdin();
    let entered_name = stdin
        .lock()
        .lines()
        .next()
        .expect("Failed to find next line")
        .expect("Could not read next line");

    // You can also use `BleId::from_mac_address("AB")` instead of `BleId::from_name()`.
    let ble_stream =
        utils::stream::build_ble_stream(&BleId::from_name(&entered_name), Duration::from_secs(5))
            .await?;
    let (mut decoded_listener, stream_api) = stream_api.connect(ble_stream).await;

    let config_id = utils::generate_rand_id();
    let stream_api = stream_api.configure(config_id).await?;

    // This loop can be broken with ctrl+c, by disabling bluetooth or by turning off the radio.
    while let Some(decoded) = decoded_listener.recv().await {
        println!("Received: {:?}", decoded);
    }

    // Note that in this specific example, this will only be called when
    // the radio is disconnected, as the above loop will never exit.
    // Typically you would allow the user to manually kill the loop,
    // for example with tokio::select!.
    let _stream_api = stream_api.disconnect().await?;

    Ok(())
}

Stats

Alt

Contributing

Contributions are welcome! If you find a bug or want to propose a new feature, please open an issue or submit a pull request.

License

This project is licensed under the GPL-3.0 License.

About

A Rust library for connecting to and configuring Meshtastic radios.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published

Languages