pounder_test/src/net/mod.rs

199 lines
5.7 KiB
Rust
Raw Normal View History

2021-04-29 17:54:16 +08:00
///! Stabilizer network management module
///!
///! # Design
///! The stabilizer network architecture supports numerous layers to permit transmission of
///! telemetry (via MQTT), configuration of run-time settings (via MQTT + Miniconf), and live data
///! streaming over raw UDP/TCP sockets. This module encompasses the main processing routines
///! related to Stabilizer networking operations.
pub use heapless;
pub use miniconf;
pub use serde;
pub mod data_stream;
pub mod messages;
pub mod miniconf_client;
pub mod network_processor;
pub mod shared;
pub mod telemetry;
2021-05-05 21:39:33 +08:00
use crate::hardware::{cycle_counter::CycleCounter, EthernetPhy, NetworkStack};
2021-07-22 20:45:58 +08:00
use data_stream::{DataStream, FrameGenerator};
2021-05-04 19:13:44 +08:00
use messages::{MqttMessage, SettingsResponse};
use miniconf_client::MiniconfClient;
use network_processor::NetworkProcessor;
use shared::NetworkManager;
use telemetry::TelemetryClient;
2021-05-05 01:52:41 +08:00
use core::fmt::Write;
use heapless::String;
2021-05-05 22:16:54 +08:00
use miniconf::Miniconf;
use serde::Serialize;
2021-06-09 18:52:13 +08:00
use smoltcp_nal::embedded_nal::SocketAddr;
2021-05-05 01:52:41 +08:00
pub type NetworkReference = shared::NetworkStackProxy<'static, NetworkStack>;
2021-03-18 03:16:13 +08:00
2021-05-05 21:39:33 +08:00
#[derive(Copy, Clone, PartialEq)]
2021-05-05 01:52:41 +08:00
pub enum UpdateState {
NoChange,
Updated,
2021-03-18 03:16:13 +08:00
}
2021-05-26 19:05:54 +08:00
#[derive(Copy, Clone, PartialEq)]
pub enum NetworkState {
SettingsChanged,
Updated,
NoChange,
}
2021-05-06 18:33:07 +08:00
/// A structure of Stabilizer's default network users.
2021-05-05 22:16:54 +08:00
pub struct NetworkUsers<S: Default + Clone + Miniconf, T: Serialize> {
2021-05-05 21:39:33 +08:00
pub miniconf: MiniconfClient<S>,
2021-05-31 20:28:57 +08:00
pub processor: NetworkProcessor,
stream: DataStream,
2021-07-22 20:45:58 +08:00
generator: Option<FrameGenerator>,
2021-05-05 22:16:54 +08:00
pub telemetry: TelemetryClient<T>,
}
impl<S, T> NetworkUsers<S, T>
where
S: Default + Clone + Miniconf,
T: Serialize,
{
2021-05-06 18:33:07 +08:00
/// Construct Stabilizer's default network users.
///
/// # Args
/// * `stack` - The network stack that will be used to share with all network users.
/// * `phy` - The ethernet PHY connecting the network.
/// * `cycle_counter` - The clock used for measuring time in the network.
/// * `app` - The name of the application.
/// * `mac` - The MAC address of the network.
///
/// # Returns
/// A new struct of network users.
2021-05-05 22:16:54 +08:00
pub fn new(
stack: NetworkStack,
phy: EthernetPhy,
cycle_counter: CycleCounter,
app: &str,
mac: smoltcp_nal::smoltcp::wire::EthernetAddress,
) -> Self {
let stack_manager =
cortex_m::singleton!(: NetworkManager = NetworkManager::new(stack))
.unwrap();
let processor = NetworkProcessor::new(
stack_manager.acquire_stack(),
phy,
cycle_counter,
);
let prefix = get_device_prefix(app, mac);
let settings = MiniconfClient::new(
stack_manager.acquire_stack(),
&get_client_id(app, "settings", mac),
&prefix,
);
let telemetry = TelemetryClient::new(
stack_manager.acquire_stack(),
&get_client_id(app, "tlm", mac),
&prefix,
);
let (generator, stream) =
data_stream::setup_streaming(stack_manager.acquire_stack());
2021-05-05 22:16:54 +08:00
NetworkUsers {
miniconf: settings,
processor,
telemetry,
stream,
generator: Some(generator),
}
}
/// Enable live data streaming.
2021-07-26 18:24:36 +08:00
pub fn enable_streaming(
&mut self,
format: data_stream::StreamFormat,
) -> FrameGenerator {
let mut generator = self.generator.take().unwrap();
generator.set_format(format);
generator
}
2021-06-15 19:18:16 +08:00
/// Direct the stream to the provided remote target.
///
/// # Args
/// * `remote` - The destination for the streamed data.
pub fn direct_stream(&mut self, remote: SocketAddr) {
if self.generator.is_none() {
self.stream.set_remote(remote);
2021-05-05 22:16:54 +08:00
}
}
2021-05-06 18:33:07 +08:00
/// Update and process all of the network users state.
///
/// # Returns
/// An indication if any of the network users indicated a state change.
2021-05-26 19:05:54 +08:00
pub fn update(&mut self) -> NetworkState {
// Update the MQTT clients.
self.telemetry.update();
// Update the data stream.
if self.generator.is_none() {
2021-05-29 00:57:23 +08:00
self.stream.process();
}
// Poll for incoming data.
2021-05-26 19:05:54 +08:00
let poll_result = match self.processor.update() {
UpdateState::NoChange => NetworkState::NoChange,
UpdateState::Updated => NetworkState::Updated,
};
2021-05-31 20:28:57 +08:00
match self.miniconf.update() {
2021-05-26 19:05:54 +08:00
UpdateState::Updated => NetworkState::SettingsChanged,
UpdateState::NoChange => poll_result,
2021-05-31 20:28:57 +08:00
}
}
2021-05-05 22:16:54 +08:00
}
2021-05-06 18:33:07 +08:00
/// Get an MQTT client ID for a client.
///
/// # Args
/// * `app` - The name of the application
/// * `client` - The unique tag of the client
/// * `mac` - The MAC address of the device.
///
/// # Returns
/// A client ID that may be used for MQTT client identification.
2021-05-05 22:16:54 +08:00
fn get_client_id(
app: &str,
client: &str,
mac: smoltcp_nal::smoltcp::wire::EthernetAddress,
) -> String<64> {
2021-05-05 22:16:54 +08:00
let mut identifier = String::new();
2021-05-10 16:57:50 +08:00
write!(&mut identifier, "{}-{}-{}", app, mac, client).unwrap();
2021-05-05 22:16:54 +08:00
identifier
2021-05-05 21:39:33 +08:00
}
/// Get the MQTT prefix of a device.
///
/// # Args
/// * `app` - The name of the application that is executing.
/// * `mac` - The ethernet MAC address of the device.
///
/// # Returns
/// The MQTT prefix used for this device.
pub fn get_device_prefix(
app: &str,
mac: smoltcp_nal::smoltcp::wire::EthernetAddress,
) -> String<128> {
// Note(unwrap): The mac address + binary name must be short enough to fit into this string. If
// they are defined too long, this will panic and the device will fail to boot.
let mut prefix: String<128> = String::new();
2021-05-10 16:57:50 +08:00
write!(&mut prefix, "dt/sinara/{}/{}", app, mac).unwrap();
prefix
}