Skip to content
Snippets Groups Projects
Verified Commit d384c6f7 authored by Volkor Barbarian Warrior's avatar Volkor Barbarian Warrior
Browse files

add db handling

parent 7a4ed80e
No related branches found
No related tags found
No related merge requests found
...@@ -55,6 +55,15 @@ dependencies = [ ...@@ -55,6 +55,15 @@ dependencies = [
"syn 2.0.95", "syn 2.0.95",
] ]
[[package]]
name = "atomic"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994"
dependencies = [
"bytemuck",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.4.0" version = "1.4.0"
...@@ -76,6 +85,15 @@ dependencies = [ ...@@ -76,6 +85,15 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
...@@ -153,6 +171,12 @@ dependencies = [ ...@@ -153,6 +171,12 @@ dependencies = [
"windows", "windows",
] ]
[[package]]
name = "bytemuck"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.5.0" version = "1.5.0"
...@@ -324,6 +348,20 @@ dependencies = [ ...@@ -324,6 +348,20 @@ dependencies = [
"log", "log",
] ]
[[package]]
name = "figment"
version = "0.10.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3"
dependencies = [
"atomic",
"pear",
"serde",
"toml",
"uncased",
"version_check",
]
[[package]] [[package]]
name = "fixedbitset" name = "fixedbitset"
version = "0.4.2" version = "0.4.2"
...@@ -491,6 +529,12 @@ dependencies = [ ...@@ -491,6 +529,12 @@ dependencies = [
"hashbrown 0.15.2", "hashbrown 0.15.2",
] ]
[[package]]
name = "inlinable_string"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
[[package]] [[package]]
name = "io-kit-sys" name = "io-kit-sys"
version = "0.4.1" version = "0.4.1"
...@@ -814,6 +858,29 @@ dependencies = [ ...@@ -814,6 +858,29 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "pear"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467"
dependencies = [
"inlinable_string",
"pear_codegen",
"yansi",
]
[[package]]
name = "pear_codegen"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147"
dependencies = [
"proc-macro2",
"proc-macro2-diagnostics",
"quote",
"syn 2.0.95",
]
[[package]] [[package]]
name = "petgraph" name = "petgraph"
version = "0.6.5" version = "0.6.5"
...@@ -870,6 +937,19 @@ dependencies = [ ...@@ -870,6 +937,19 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "proc-macro2-diagnostics"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.95",
"version_check",
"yansi",
]
[[package]] [[package]]
name = "prost" name = "prost"
version = "0.11.9" version = "0.11.9"
...@@ -1072,6 +1152,16 @@ dependencies = [ ...@@ -1072,6 +1152,16 @@ dependencies = [
"smallvec", "smallvec",
] ]
[[package]]
name = "rusqlite_migration"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "923b42e802f7dc20a0a6b5e097ba7c83fe4289da07e49156fecf6af08aa9cd1c"
dependencies = [
"log",
"rusqlite",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.24" version = "0.1.24"
...@@ -1156,6 +1246,15 @@ dependencies = [ ...@@ -1156,6 +1246,15 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_spanned"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "serialport" name = "serialport"
version = "4.6.1" version = "4.6.1"
...@@ -1383,6 +1482,40 @@ dependencies = [ ...@@ -1383,6 +1482,40 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "toml"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.41" version = "0.1.41"
...@@ -1440,6 +1573,15 @@ dependencies = [ ...@@ -1440,6 +1573,15 @@ dependencies = [
"tracing-log", "tracing-log",
] ]
[[package]]
name = "uncased"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697"
dependencies = [
"version_check",
]
[[package]] [[package]]
name = "unescaper" name = "unescaper"
version = "0.1.5" version = "0.1.5"
...@@ -1673,6 +1815,15 @@ version = "0.52.6" ...@@ -1673,6 +1815,15 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.6.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "xml-rs" name = "xml-rs"
version = "0.8.24" version = "0.8.24"
...@@ -1683,16 +1834,27 @@ checksum = "ea8b391c9a790b496184c29f7f93b9ed5b16abb306c05415b68bcc16e4d06432" ...@@ -1683,16 +1834,27 @@ checksum = "ea8b391c9a790b496184c29f7f93b9ed5b16abb306c05415b68bcc16e4d06432"
name = "yamm" name = "yamm"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bincode",
"fern", "fern",
"figment",
"humantime", "humantime",
"lazy_static",
"log", "log",
"meshtastic", "meshtastic",
"rusqlite", "rusqlite",
"rusqlite_migration",
"serde",
"tokio", "tokio",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
] ]
[[package]]
name = "yansi"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.7.35" version = "0.7.35"
......
...@@ -11,4 +11,9 @@ meshtastic = "0.1.6" ...@@ -11,4 +11,9 @@ meshtastic = "0.1.6"
tokio = "1.42.0" tokio = "1.42.0"
tracing = "0.1.41" tracing = "0.1.41"
tracing-subscriber = "0.3.19" tracing-subscriber = "0.3.19"
rusqlite = { version = "0.32.0", features = ["bundled"] } rusqlite = { version = "0.32.0", features = ["bundled"] }
\ No newline at end of file rusqlite_migration = "1.3.1"
lazy_static = "1.5.0"
figment = {version = "0.10.19", features = ["toml", "env"]}
serde = "1.0.217"
bincode = "1.3.3"
...@@ -13,12 +13,12 @@ ...@@ -13,12 +13,12 @@
**Y**et **A**nother **M**eshtastic **M**ap **Y**et **A**nother **M**eshtastic **M**ap
Inspired slightly by MeshInfo. Inspired slightly by [MeshInfo](https://github.com/MeshAddicts/meshinfo).
## What it does ## What it does
- Logs meshtastic broadcasts - Logs meshtastic packets
- Saves them to a database - Saves them to a database
- Serves the data to a future GUI - Serves the data to a future GUI
- Serves the data to a public webpage - Serves the data to a public webpage
...@@ -26,8 +26,8 @@ Inspired slightly by MeshInfo. ...@@ -26,8 +26,8 @@ Inspired slightly by MeshInfo.
## What it doesn't ## What it doesn't
- Runs meshtastic - Runs meshtastic
- Had a GUI (yet) - Had a GUI (yet?)
- Lets you send messages (yet) - Lets you send messages (yet?)
## Installation ## Installation
......
[config] [server]
host = "0.0.0.0"
port = 8080
# Connection Type [database]
# Can be one of the following: Serial, Tcp, Mqtt db_name = "yamm.db"
connection_type = "Tcp"
# Serial Port [logging]
## If connection_type is Serial, use this device to connect level = "yamm=debug,rusqlite=debug,meshtastic=debug"
serial_port = "/dev/something"
# IP Port [meshconfig]
## If connection_type is Tcp, use this ip & port combo to connect # How should we connect to the meshtastic node? (Tcp, Serial, Mqtt)
ip_port = "127.0.0.1:4403" connection_type = "Tcp"
# MQTT ## If connection_type is Serial, use this device to connect
## If connection_type is MQTT, use this to connect. serial_port = "Set this from whatever 'available ports' says."
### TODO!
## If connection_type is TCP or MQTT, use this ip & port combo to connect
ip = "192.168.1.128"
port = 4403
\ No newline at end of file
CREATE TABLE MyNodeInfo (
my_node_num INTEGER PRIMARY KEY,
reboot_count INTEGER NOT NULL,
min_app_version INTEGER NOT NULL
);
CREATE TABLE Node (
id INTEGER PRIMARY KEY, -- internal yamm packet numbering
num INT, -- "node number" wtf does that mean???
user_id TEXT, -- the typical !c6744jd whatever code
user_lname TEXT, -- User's Long name
user_sname TEXT, -- User's Short name
-- mac_addr BLOB -- Deprecated in 2.1.x, esp32 only.
hw_model TEXT,
is_licensed INTEGER,
role TEXT,
latitude_i INTEGER, -- multiply by 1e-7 to get degrees in float.
longitude_i INTEGER, -- multiply by 1e-7 to get degrees in float.
altitude INTEGER,
-- time: INTEGER, -- Disabled, only used for syncing time to note.
location_source TEXT, -- Where does the location come from?
gps_timestamp INTEGER, -- What time does the gps say it is?
altitude_source TEXT, -- Where does the altitude come from?
pdop INTEGER, -- Horizontal, Vertical, and Position Dilution of precision, in 1/100 units.
hdop INTEGER,
vdop INTEGER,
gps_accuracy INTEGER, -- hardware constant in mm, used to calculate true accuracy (default to about 3m)
ground_speed INTEGER, -- in m/s
ground_track INTEGER, -- direction of motion
fix_quality INTEGER, -- GPS Fix (something called NMEA GxGSA Statement)
fix_type INTEGER, -- fix type, whatever that means
sats_in_view INTEGER, -- How many satellites we can see
sensor_id INTEGER, -- Just incase there's multiple gps devices on the node
next_update INTEGER, -- How long until we ask for GPS (in seconds)
seq_number INTEGER, -- Sequence number
precision_bits INTEGER, -- How accurate the position is
snr REAL, -- Signal to Noise ratio of this message, measured by receiver
last_heard INTEGER, -- Last time we heard the message
battery_level INTEGER, -- Battery level, if it has one
voltage REAL, -- Voltage from the power supply
channel_utilization REAL, -- Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise).
air_util_tx REAL, -- Percent of airtime for transmission used within the last hour.
channel INTEGER, -- The local channel we heard the node on.
via_mqtt INTEGER, -- Did we see this node over MQTT instead of LoRA?
hops_away INTEGER -- Number of hops away from us in the network. (0 is direct)
);
CREATE TABLE Channel (
channel_index INTEGER PRIMARY KEY, -- Index of the channel
psk BLOB, -- Encryption of the channel
name TEXT, -- <12 bytes channel name.
id INTEGER, -- used to create global unique channel name, (name.id)
uplink_enabled INTEGER, -- Are messages on the mesh sent to MQTT via other nodes?
downlink_enabled INTEGER, -- Are messages seen on the internet sent over LoRA?
position_precision INTEGER, -- How many bits of precision are sent in position packets?
role TEXT -- General 'status' of the channel
);
CREATE TABLE DeviceConfig (
role INTEGER, -- Node's Role
serial_enabled INTEGER, -- Disables the SerialConsole
debug_log_enabled INTEGER, -- defaults off after connection
button_gpio INTEGER, -- lets you change the buttons
buzzer_gpio INTEGER, -- pin for the buzzer
rebroadcast_mode INTEGER, -- role of the node
node_info_broadcast_secs INTEGER,
double_tap_as_button_press INTEGER,
is_managed INTEGER, -- if set, harder to config
disable_triple_click INTEGER
);
CREATE TABLE PositionConfig (
position_broadcast_secs INTEGER,
position_broadcast_smart_enabled INTEGER,
fixed_position INTEGER,
gps_enabled INTEGER,
gps_update_interval INTEGER,
gps_attempt_time INTEGER,
position_flags INTEGER,
rx_gpio INTEGER,
tx_gpio INTEGER,
broadcast_smart_minimum_distance INTEGER,
broadcast_smart_minimum_interval_secs INTEGER,
gps_en_gpio INTEGER,
gps_mode INTEGER
);
CREATE TABLE PowerConfig (
is_power_saving INTEGER,
on_battery_shutdown_after_secs INTEGER,
adc_multiplier_override REAL,
wait_bluetooth_secs INTEGER,
sds_secs INTEGER,
ls_secs INTEGER,
min_wake_secs INTEGER,
device_battery_ina_address INTEGER
);
CREATE TABLE NetworkConfig (
wifi_enabled INTEGER,
wifi_ssid TEXT,
wifi_psk TEXT,
ntp_server TEXT,
eth_enabled INTEGER,
address_mode INTEGER,
ip INTEGER,
gateway INTEGER,
subnet INTEGER,
dns INTEGER,
rsyslog_server TEXT
);
CREATE TABLE DisplayConfig (
screen_on_secs INTEGER,
gps_format INTEGER,
auto_screen_carousel_secs INTEGER,
compass_north_top INTEGER,
flip_screen INTEGER,
units INTEGER,
oled INTEGER,
displaymode INTEGER,
heading_bold INTEGER,
wake_on_tap_or_motion INTEGER
);
CREATE TABLE LoRaConfig (
use_preset INTEGER,
modem_preset INTEGER,
bandwidth INTEGER,
spread_factor INTEGER,
coding_rate INTEGER,
frequency_offset REAL,
region INTEGER,
hop_limit INTEGER,
tx_enabled INTEGER,
tx_power INTEGER,
channel_num INTEGER,
override_duty_cycle INTEGER,
sx126x_rx_boosted_gain INTEGER,
override_frequency REAL,
ignore_incoming BLOB,
ignore_mqtt INTEGER
);
CREATE TABLE BluetoothConfig (
enabled INTEGER,
mode INTEGER,
fixed_pin INTEGER
);
-- Module Configs --
-- MQTT
CREATE TABLE MqttConfig (
enabled INTEGER,
address TEXT,
username TEXT,
password TEXT,
encryption_enabled INTEGER,
json_enabled INTEGER,
tls_enabled INTEGER,
root TEXT,
proxy_to_client_enabled INTEGER,
map_reporting_enabled INTEGER,
publish_interval_secs INTEGER,
position_precision INTEGER
);
-- Serial
CREATE TABLE SerialConfig (
enabled INTEGER,
echo INTEGER,
rxd INTEGER,
txd INTEGER,
baud INTEGER,
timeout INTEGER,
mode INTEGER,
override_console_serial_port INTEGER
);
-- External Notification
CREATE TABLE ExternalNotificationConfig (
enabled INTEGER,
output_ms INTEGER,
output INTEGER,
output_vibra INTEGER,
output_buzzer INTEGER,
active INTEGER,
alert_message INTEGER,
alert_message_vibra INTEGER,
alert_message_buzzer INTEGER,
alert_bell INTEGER,
alert_bell_vibra INTEGER,
alert_bell_buzzer INTEGER,
use_pwm INTEGER,
nag_timeout INTEGER,
use_i2s_as_buzzer INTEGER
);
-- Store Forward
CREATE TABLE StoreForwardConfig (
enabled INTEGER,
heartbeat INTEGER,
records INTEGER,
history_return_max INTEGER,
history_return_window INTEGER
);
-- Range Test
CREATE TABLE RangeTestConfig (
enabled INTEGER,
sender INTEGER,
save INTEGER
);
-- Telemetry
CREATE TABLE TelemetryConfig (
device_update_interval INTEGER,
environment_update_interval INTEGER,
environment_measurement_enabled INTEGER,
environment_screen_enabled INTEGER,
environment_display_fahrenheit INTEGER,
air_quality_enabled INTEGER,
air_quality_interval INTEGER,
power_measurement_enabled INTEGER,
power_update_interval INTEGER,
power_screen_enabled INTEGER
);
-- Canned Message
CREATE TABLE CannedMessageConfig (
rotary1_enabled INTEGER,
inputbroker_pin_a INTEGER,
inputbroker_pin_b INTEGER,
inputbroker_pin_press INTEGER,
inputbroker_event_cw INTEGER,
inputbroker_event_ccw INTEGER,
inputbroker_event_press INTEGER,
updown1_enabled INTEGER,
enabled INTEGER,
allow_input_source TEXT,
send_bell INTEGER
);
-- Audio
CREATE TABLE AudioConfig (
codec2_enabled INTEGER,
ptt_pin INTEGER,
bitrate INTEGER,
i2s_ws INTEGER,
i2s_sd INTEGER,
i2s_din INTEGER,
i2s_sck INTEGER
);
-- Remote Hardware
CREATE TABLE RemoteHardwareConfig (
enabled INTEGER,
allow_undefined_pin_access INTEGER,
available_pins BLOB -- Use BLOB to store complex structures like a vector of structs
);
-- NeighborInfo
CREATE TABLE NeighborInfoConfig (
enabled INTEGER,
update_interval INTEGER
);
-- AmbientLighting
CREATE TABLE AmbientLightingConfig (
led_state INTEGER,
led_current INTEGER,
red INTEGER,
green INTEGER,
blue INTEGER
);
-- Detection Sensor (any gpio pin alarm)
CREATE TABLE DetectionSensorConfig (
enabled INTEGER,
minimum_broadcast_secs INTEGER,
state_broadcast_secs INTEGER,
send_bell INTEGER,
name TEXT,
monitor_pin INTEGER,
detection_triggered_high INTEGER,
use_pullup INTEGER
);
-- Pax counter
CREATE TABLE PaxcounterConfig (
enabled INTEGER,
paxcounter_update_interval INTEGER
);
-- MeshPacket Main Table
CREATE TABLE MeshPacket (
primary_id INTEGER PRIMARY KEY AUTOINCREMENT,
message_from INTEGER,
message_to INTEGER,
channel INTEGER,
id INTEGER, -- Unique ID for this packet, but not unique enough to use as a primary key, unfortunately.
rx_time INTEGER,
rx_snr REAL,
hop_limit INTEGER,
want_ack INTEGER,
priority INTEGER,
rx_rssi INTEGER,
delayed INTEGER,
via_mqtt INTEGER,
hop_start INTEGER,
variant_payload_id INTEGER,
FOREIGN KEY (variant_payload_id) REFERENCES VariantPayload(variant_id)
);
-- VariantPayload Table
CREATE TABLE VariantPayload (
variant_id INTEGER PRIMARY KEY AUTOINCREMENT,
);
/// Full Config Structure to manage application settings use serde::Deserialize;
pub struct Config {
/// Holds the individual config segments.
#[derive(Debug, Clone, Deserialize, Default)]
pub struct AppConfig {
pub server: ServerConfig,
pub database: DatabaseConfig,
pub logging: LoggingConfig,
pub meshconfig: MeshConfig,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ServerConfig {
pub host: String,
pub port: u16,
}
/// Holds the config for the database
#[derive(Debug, Clone, Deserialize)]
pub struct DatabaseConfig {
pub db_name: String,
}
/// Holds the config for logging
#[derive(Debug, Clone, Deserialize)]
pub struct LoggingConfig {
pub level: String,
}
/// Holds the config for the meshtastic node.
#[derive(Debug, Clone, Deserialize)]
pub struct MeshConfig {
pub connection_type: ConnectionType, pub connection_type: ConnectionType,
pub serial_port: Option<String>, pub serial_port: Option<String>,
pub ip_port: Option<String>, pub ip: String,
pub port: u16
} }
/// Enum to define the connection type /// Enum to define the connection type, defaulting to TCP
#[derive(Default)] #[derive(Default, Debug, Clone, Deserialize)]
pub enum ConnectionType { pub enum ConnectionType {
#[default] #[default]
Tcp, Tcp,
...@@ -14,3 +45,41 @@ pub enum ConnectionType { ...@@ -14,3 +45,41 @@ pub enum ConnectionType {
Mqtt, Mqtt,
} }
// Defaults
impl Default for ServerConfig {
fn default() -> Self {
Self {
host: "localhost".to_string(),
port: 8080,
}
}
}
impl Default for DatabaseConfig {
fn default() -> Self {
Self {
db_name: "yamm.db".to_string(),
}
}
}
impl Default for LoggingConfig {
fn default() -> Self {
Self {
level: "INFO".to_string(),
}
}
}
impl Default for MeshConfig {
fn default() -> Self {
Self {
connection_type: ConnectionType::Tcp,
serial_port: None,
ip: "192.168.1.2".to_string(),
port: 4403,
}
}
}
\ No newline at end of file
src/db.rs 0 → 100644
This diff is collapsed.
use figment::{Figment, providers::{Format, Toml, Env}};
use std::io::{self, BufRead}; use lazy_static::lazy_static;
use std::time::SystemTime; use meshtastic::api::{StreamApi, StreamHandle};
use meshtastic::api::StreamApi;
use meshtastic::utils; use meshtastic::utils;
use meshtastic::protobufs::*; use meshtastic::protobufs::*;
use packets::parse;
use tokio::{net::TcpStream, sync::mpsc::UnboundedReceiver};
use tracing::{debug, error, info, Level}; use tracing::{debug, error, info, Level};
use tracing_subscriber::{fmt, FmtSubscriber}; use tracing_subscriber::FmtSubscriber;
use tracing_subscriber::prelude::*;
mod nodes; mod nodes;
mod packets; mod packets;
mod db;
mod config;
use crate::config::AppConfig;
// Setup the config globally because I can't figure out how to pass it to functions I don't call directly.
// This is evaluated at runtime, and not compilation. \o/
// Also, we try to merge configs. so envvars > config > defaults > error
lazy_static! {
pub static ref CONFIG: AppConfig = {
let config = Figment::new()
.merge(Toml::file("config.toml"))
.merge(Env::prefixed("yamm_"))
.extract()
.unwrap_or_default();
tracing::info!("Loaded Config!");
tracing::debug!("full config: {:?}", config);
config
};
}
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> { async fn main() -> Result<(), Box<dyn std::error::Error>> {
...@@ -23,37 +42,53 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { ...@@ -23,37 +42,53 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing::subscriber::set_global_default(subscriber) tracing::subscriber::set_global_default(subscriber)
.expect("setting default subscriber failed"); .expect("setting default subscriber failed");
// Hello World!
info!("Y(et) A(nother) M(eshtastic) M(ap) - v0.1.0"); info!("Y(et) A(nother) M(eshtastic) M(ap) - v0.1.0");
// set up new connection // set up new connection
// TODO: setup multiple types
let stream_api = StreamApi::new(); let stream_api = StreamApi::new();
// Set Address and port // Different connection types have different setups.
// TODO: read from config let mut tcp_stream: StreamHandle<TcpStream>;
let address = "127.0.0.1:4403".to_string(); //let mut serial_stream: StreamHandle<SerialStream>; // SerialStream isn't a valid type???
match &CONFIG.meshconfig.connection_type {
// Connect over TCP config::ConnectionType::Tcp => {
let tcp_stream = utils::stream::build_tcp_stream(address).await?; // Build the tcp stream object from config.
let (mut decoded_listener, stream_api) = stream_api.connect(tcp_stream).await; let address = &CONFIG.meshconfig.ip;
let config_id = utils::generate_rand_id(); let port = &CONFIG.meshconfig.port.to_string();
let stream_api = stream_api.configure(config_id).await?; let tcp = format!("{}:{}", address, port);
// Read loop, exit with Ctrl+C or disconnecting node.
while let Some(decoded) = decoded_listener.recv().await {
// New Message!
debug!("Received: {:?}", decoded);
// Parse message
// Save to DB // Connect over TCP
let tcp_stream = utils::stream::build_tcp_stream(tcp).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?;
// Read loop, exit with Ctrl+C or disconnecting node.
while let Some(decoded) = decoded_listener.recv().await {
// New Message!
debug!("Received: {:?}", decoded);
// Parse message
parse(&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?;
},
config::ConnectionType::Serial => {
let available_ports = utils::stream::available_serial_ports()?;
info!("Available ports, please set in config.: {:?}", available_ports);
todo!("Not yet Implemented. See https://git.volkor.me/Volkor/yamm/-/issues/2")
},
config::ConnectionType::Mqtt => {
todo!("Not yet Implemented. See https://git.volkor.me/Volkor/yamm/-/issues/3")
},
} }
// 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(()) Ok(())
} }
\ No newline at end of file
use std::path::Path;
use config::device_config;
use from_radio::PayloadVariant; use from_radio::PayloadVariant;
use meshtastic::protobufs::*; use meshtastic::protobufs::*;
use tracing::{debug, error}; use tracing::{debug, error};
use crate::db::Database;
/// Parses all incoming packets, handing them out to the correct handler. /// Parses all incoming packets, handing them out to the correct handler.
pub fn parse(message: &FromRadio) -> bool { pub fn parse(message: &FromRadio) -> bool {
debug!("Parsing Message from radio"); // debug!("Parsing Message from radio: {:?}", &message);
// Handle all types of messages from the radio here. // Handle all types of messages from the radio here.
match message.payload_variant { match message.payload_variant {
// A normal message // A normal message
Some(PayloadVariant::Packet(ref packet)) => { Some(PayloadVariant::Packet(ref packet)) => {
debug!("New Message Packet!");
parse_packet(packet); parse_packet(packet);
}, },
// Information about the local node // Information about the local node
Some(PayloadVariant::MyInfo(ref info)) => { Some(PayloadVariant::MyInfo(ref info)) => {
debug!("New MyNodeInfo Packet");
parse_myinfo(info); parse_myinfo(info);
}, },
// Information about a remote node // Information about a remote node
Some(PayloadVariant::NodeInfo(ref node_info)) => { Some(PayloadVariant::NodeInfo(ref node_info)) => {
debug!("New NodeInfo Packet!");
parse_nodeinfo(node_info); parse_nodeinfo(node_info);
}, },
// Information about the local node's config // Information about the local node's config
Some(PayloadVariant::Config(ref config)) => { Some(PayloadVariant::Config(ref config)) => {
debug!("New Config Packet!");
parse_config(config); parse_config(config);
}, },
// Information about the local node's module config // Information about the local node's module config
Some(PayloadVariant::ModuleConfig(ref module_config)) => { Some(PayloadVariant::ModuleConfig(ref module_config)) => {
debug!("New ModuleConfig Packet!");
parse_module_config(module_config); parse_module_config(module_config);
}, },
// Information about one of the 8 channels in (potential) use. // Information about one of the 8 channels in (potential) use.
Some(PayloadVariant::Channel(ref channel_info)) => { Some(PayloadVariant::Channel(ref channel_info)) => {
debug!("New Channel Packet!");
parse_channel_info(channel_info); parse_channel_info(channel_info);
}, },
// Information about the queue (messages to send soon) // Information about the queue (messages to send soon)
Some(PayloadVariant::QueueStatus(ref queue_status)) => { Some(PayloadVariant::QueueStatus(ref queue_status)) => {
debug!("New Message Packet!");
parse_queue_info(queue_status); parse_queue_info(queue_status);
}, },
...@@ -49,35 +61,110 @@ pub fn parse(message: &FromRadio) -> bool { ...@@ -49,35 +61,110 @@ pub fn parse(message: &FromRadio) -> bool {
fn parse_packet(packet: &MeshPacket) { fn parse_packet(packet: &MeshPacket) {
// Handle packet data // Handle packet data
debug!("Parsing MeshPacket Packet: {:#?}", &packet);
todo!() todo!()
} }
fn parse_myinfo(packet: &MyNodeInfo) { fn parse_myinfo(packet: &MyNodeInfo) {
// Check the last MyNodeInfo packet from the DB. If it's different, save it. debug!("Parsing MyNodeInfo Packet: {:#?}", &packet);
todo!() let _ = Database::update_mynodeinfo(packet);
} }
fn parse_nodeinfo(node_info: &NodeInfo) { fn parse_nodeinfo(node_info: &NodeInfo) {
// Handle NodeInfo data // Handle NodeInfo data
todo!() debug!("Parsing MyNodeInfo Packet: {:#?}", &node_info);
let _ = Database::update_nodeinfo(node_info);
} }
fn parse_config(config: &Config) { fn parse_config(config: &Config) {
// Handle Config data // Handle Config data
todo!() debug!("Parsing Config Packet: {:#?}", &config);
// Match and destructure the payload_variant
if let Some(payload_variant) = config.payload_variant.clone() {
match payload_variant {
config::PayloadVariant::Device(device_config) => {
let _ = Database::update_deviceconfig(&device_config);
},
config::PayloadVariant::Position(position_config) => {
let _ = Database::update_position_config(&position_config);
},
config::PayloadVariant::Power(power_config) => {
let _ = Database::update_power_config(&power_config);
},
config::PayloadVariant::Network(network_config) => {
let _ = Database::update_network_config(&network_config);
},
config::PayloadVariant::Display(display_config) => {
let _ = Database::update_display_config(&display_config);
},
config::PayloadVariant::Lora(lora_config) => {
let _ = Database::update_lora_config(&lora_config);
},
config::PayloadVariant::Bluetooth(bluetooth_config) => {
let _ = Database::update_bluetooth_config(&bluetooth_config);
},
}
}
} }
fn parse_module_config(module_config: &ModuleConfig) { fn parse_module_config(module_config: &ModuleConfig) {
debug!("Parsing Module Packet: {:#?}", &module_config);
// Handle ModuleConfig data // Handle ModuleConfig data
todo!() // Match and destructure the payload_variant
if let Some(payload_variant) = module_config.payload_variant.clone() {
match payload_variant {
module_config::PayloadVariant::Mqtt(mqtt_config) => {
let _ = Database::update_mqtt_config(&mqtt_config);
},
module_config::PayloadVariant::Serial(serial_config) => {
let _ = Database::update_serial_config(&serial_config);
},
module_config::PayloadVariant::ExternalNotification(external_notification_config) => {
let _ = Database::update_externalnotification_config(&external_notification_config);
},
module_config::PayloadVariant::StoreForward(store_forward_config) => {
let _ = Database::update_storeforward_config(&store_forward_config);
},
module_config::PayloadVariant::RangeTest(range_test_config) => {
let _ = Database::update_rangetest_config(&range_test_config);
},
module_config::PayloadVariant::Telemetry(telemetry_config) => {
let _ = Database::update_telemetry_config(&telemetry_config);
},
module_config::PayloadVariant::CannedMessage(canned_message_config) => {
let _ = Database::update_cannedmessage_config(&canned_message_config);
},
module_config::PayloadVariant::Audio(audio_config) => {
let _ = Database::update_audio_config(&audio_config);
},
module_config::PayloadVariant::RemoteHardware(remote_hardware_config) => {
let _ = Database::update_remotehardware_config(&remote_hardware_config);
},
module_config::PayloadVariant::NeighborInfo(neighbor_info_config) => {
let _ = Database::update_neighbourinfo_config(&neighbor_info_config);
},
module_config::PayloadVariant::AmbientLighting(ambient_lighting_config) => {
let _ = Database::update_ambientlighting_config(&ambient_lighting_config);
},
module_config::PayloadVariant::DetectionSensor(detection_sensor_config) => {
let _ = Database::update_detectionsensor_config(&detection_sensor_config);
},
module_config::PayloadVariant::Paxcounter(paxcounter_config) => {
let _ = Database::update_paxcounter_config(&paxcounter_config);
},
}
}
} }
fn parse_channel_info(channel_info: &Channel) { fn parse_channel_info(channel_info: &Channel) {
debug!("Parsing Channel Packet: {:#?}", &channel_info);
// Handle ChannelInfo data // Handle ChannelInfo data
todo!() let _ = Database::update_channel(channel_info);
} }
fn parse_queue_info(queue_info: &QueueStatus) { fn parse_queue_info(queue_info: &QueueStatus) {
debug!("Parsing Queue Packet: {:#?}", &queue_info);
// Handle QueueInfo data // Handle QueueInfo data
todo!() todo!()
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment