diff --git a/src/gate.rs b/src/gate.rs index 68443e15f82b144d599bc88cf286f5525b67bee5..c94f20a333be117826e0ca2f96c50d1392ae7742 100644 --- a/src/gate.rs +++ b/src/gate.rs @@ -14,8 +14,9 @@ use ham_cats::{ packet::Packet, whisker::{Gps, Identification, Route}, }; -use std::time::Duration; -use tokio::sync::{broadcast, mpsc}; +use std::sync::Arc; +use std::time::{Duration, Instant}; +use tokio::sync::{broadcast, mpsc, Mutex}; use tokio_stream::StreamExt; use tonic::{transport::Channel, Request}; use uuid::Uuid; @@ -28,7 +29,10 @@ pub fn beacon_forever( modem_send: mpsc::Sender<Vec<u8>>, felinet_send: broadcast::Sender<SemiPacketIn>, uuid: Uuid, + temperature_mutex: Arc<Mutex<f32>>, ) -> anyhow::Result<()> { + let start_time = Instant::now(); + let mut buf = [0; MAX_PACKET_LEN]; let mut packet = Packet::new(&mut buf); packet @@ -78,6 +82,8 @@ pub fn beacon_forever( info_builder = info_builder.tx_power(power as f64); } + // This is going to be overwritten. + // We add it now to ensure there are no errors when we unwrap it later packet .add_node_info(info_builder.build()) .map_err(|e| anyhow!("Could not add info to beacon packet: {e}"))?; @@ -99,27 +105,69 @@ pub fn beacon_forever( .add_route(r) .map_err(|e| anyhow!("Could not add route to beacon packet: {e}"))?; - let semi = internet_packet - .semi_encode() - .map_err(|(e, _)| anyhow!("Could not encode beacon packet: {e}"))? - .to_vec(); - let semi = SemiPacketIn { - raw: semi, - uuid: uuid.into(), - }; - - let mut full = [0; MAX_PACKET_LEN]; - let mut full = Buffer::new_empty(&mut full); - rf_packet - .fully_encode(&mut full) - .map_err(|e| anyhow!("Could not encode beacon packet: {e}"))?; + let rf_packet_bytes = rf_packet.encode().to_vec(); + let internet_packet_bytes = internet_packet.encode().to_vec(); + tokio::task::spawn(async move { + let mut rf_packet_buf = [0; MAX_PACKET_LEN]; + let mut rf_packet_buf = Buffer::new_empty(&mut rf_packet_buf); + rf_packet_buf.extend(&rf_packet_bytes); + let mut rf_packet = Packet::decode(rf_packet_buf).expect("Could not re-create rf packet"); - let full = full.to_vec(); + let mut internet_packet_buf = [0; MAX_PACKET_LEN]; + let mut internet_packet_buf = Buffer::new_empty(&mut internet_packet_buf); + internet_packet_buf.extend(&internet_packet_bytes); + let mut internet_packet = + Packet::decode(internet_packet_buf).expect("Could not re-create internet packet"); + + let mut full = [0; MAX_PACKET_LEN]; + let mut tmp = [0; MAX_PACKET_LEN]; - tokio::task::spawn(async move { loop { tokio::time::sleep(period).await; + let uptime = (Instant::now() - start_time) + .as_secs() + .try_into() + .expect("Could not calculate uptime"); + + let info = info_builder + .uptime(uptime) + .xcvr_temperature( + temperature_mutex + .lock() + .await + .clamp(i8::MIN as f32, i8::MAX as f32) as i8, + ) + .build(); + + rf_packet.clear_node_info(); + rf_packet + .add_node_info(info) + .expect("Could not add node info to rf packet"); + + let mut full = Buffer::new_empty(&mut full); + rf_packet + .clone_backing(&mut tmp) + .fully_encode(&mut full) + .expect("Could not fully encode beacon packet"); + + let full = full.to_vec(); + + internet_packet.clear_node_info(); + internet_packet + .add_node_info(info) + .expect("Could not add node info to rf packet"); + + let semi = internet_packet + .clone_backing(&mut tmp) + .semi_encode() + .expect("Could not encode beacon packet") + .to_vec(); + let semi = SemiPacketIn { + raw: semi, + uuid: uuid.into(), + }; + let _ = modem_send.send(full.clone()).await; let _ = felinet_send.send(semi.clone()); } diff --git a/src/main.rs b/src/main.rs index 77343ba8be93ada3d4c0de0a6c335cdfb5dbdf59..b02de831ead069cfa17ba0e67c6d3a60a6f696ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,7 +41,7 @@ async fn main() -> anyhow::Result<()> { let (packet_tx, packet_receive) = mpsc::channel(16); let (packet_send, packet_rx) = mpsc::channel(16); - let radio = RadioManager::new(packet_tx, packet_rx).unwrap(); + let radio = RadioManager::new(packet_tx, packet_rx).expect("Could not initialize radio"); match cli.xmit_test { Some(freq) => xmit_test(&config, freq, radio, packet_send).await?, @@ -109,6 +109,8 @@ async fn gate_forever( ) -> anyhow::Result<()> { let uuid = Uuid::new_v4(); + let temperature_mutex = radio.temperature_mutex(); + tokio::task::spawn(async move { loop { if let Err(e) = radio.process_forever().await { @@ -119,7 +121,13 @@ async fn gate_forever( let tx = broadcast::Sender::new(16); - beacon_forever(config, packet_send.clone(), tx.clone(), uuid)?; + beacon_forever( + config, + packet_send.clone(), + tx.clone(), + uuid, + temperature_mutex, + )?; let endpoint = Endpoint::from_str(&config.felinet.address)? .keep_alive_while_idle(true) diff --git a/src/radio.rs b/src/radio.rs index 0d4d9e53b4ceddfc1b1775f206901ca221779522..77f7c0f448cd1504ba23881c981be008082895ec 100644 --- a/src/radio.rs +++ b/src/radio.rs @@ -6,8 +6,14 @@ use rppal::{ hal::Delay, spi::{Bus, Mode, SlaveSelect, Spi}, }; -use std::time::{Duration, Instant}; -use tokio::sync::mpsc::{error::TryRecvError, Receiver, Sender}; +use std::{ + sync::Arc, + time::{Duration, Instant}, +}; +use tokio::sync::{ + mpsc::{error::TryRecvError, Receiver, Sender}, + Mutex, +}; pub const MAX_PACKET_LEN: usize = 8191; @@ -17,6 +23,7 @@ pub struct RadioManager { tx: Sender<(Vec<u8>, f64)>, rx: Receiver<Vec<u8>>, rx_buf: [u8; MAX_PACKET_LEN], + temperature: Arc<Mutex<f32>>, } impl RadioManager { @@ -33,12 +40,14 @@ impl RadioManager { radio.set_channel(20); let rx_buf = [0; MAX_PACKET_LEN]; + let temperature = Arc::new(Mutex::new(radio.get_temp()?)); Ok(Self { radio, tx, rx, rx_buf, + temperature, }) } @@ -46,10 +55,16 @@ impl RadioManager { self.radio.set_channel(channel); } + pub fn temperature_mutex(&self) -> Arc<Mutex<f32>> { + self.temperature.clone() + } + pub async fn process_forever(&mut self) -> anyhow::Result<()> { loop { self.tick().await?; + *self.temperature.lock().await = self.radio.get_temp()?; + match self.rx.try_recv() { Ok(pkt) => { self.tx(&pkt).await?;