diff --git a/src/applogic/mod.rs b/src/applogic/mod.rs index 0ced524..55672a7 100644 --- a/src/applogic/mod.rs +++ b/src/applogic/mod.rs @@ -118,7 +118,6 @@ pub struct TimingData { pub max_end_sec: Option, } -#[cfg(feature = "spat")] impl TimingData { pub fn new(value: &map::SignalGroup, now: chrono::DateTime) -> Option { let min = value diff --git a/src/ble.rs b/src/ble.rs index e58ffb0..8fc86e5 100644 --- a/src/ble.rs +++ b/src/ble.rs @@ -6,7 +6,6 @@ use core::cell::RefCell; use critical_section::Mutex; -use crossbeam_queue::ArrayQueue; use esp_backtrace as _; use log::{info, warn}; use trouble_host::prelude::*; @@ -17,9 +16,7 @@ pub const CONTROLLER_SLOTS: usize = 20; const CONNECTIONS_MAX: usize = 1; const L2CAP_CHANNELS_MAX: usize = 1; -pub static CLIENT_CONNECTED: Mutex> = Mutex::new(RefCell::new(false)); -pub static TX_DATA: Mutex>>> = - Mutex::new(RefCell::new(None)); +pub static TX_DATA: Mutex>> = Mutex::new(RefCell::new(None)); // TODO: this needs to be an array! pub static RX_DATA: Mutex>> = Mutex::new(RefCell::new(None)); pub enum BleSendable { @@ -85,10 +82,6 @@ pub fn make_controller( esp_radio::ble::controller::BleConnector<'static>, CONTROLLER_SLOTS, > { - critical_section::with(|cs| { - TX_DATA.borrow(cs).replace(Some(ArrayQueue::new(2))); - }); - let transport = esp_radio::ble::controller::BleConnector::new( bt_peripheral, esp_radio::ble::Config::default(), @@ -127,15 +120,10 @@ pub async fn run( Ok(conn) => { // set up tasks when the connection is established to a central, so they don't run when no one is connected. let a = gatt_events_task(&server, &conn); - let b = publishing_task(&server, &conn); - - // run until any task ends (usually because the connection has been closed), then return to advertising state. + let b = custom_task(&server, &conn); + // run until any task ends (usually because the connection has been closed), + // then return to advertising state. embassy_futures::select::select(a, b).await; - - critical_section::with(|cs| { - let value_ref = CLIENT_CONNECTED.borrow(cs); - let _ = value_ref.replace(false); - }); } Err(e) => { panic!("BLE ADV: fatal error {e:?}"); @@ -146,21 +134,6 @@ pub async fn run( .await; } -pub fn update(payload: BleSendable) { - critical_section::with(|cs| { - // only add to queue when someone is connected - if *CLIENT_CONNECTED.borrow(cs).borrow() { - let queue_rc = TX_DATA.borrow(cs).borrow(); - // unwrap is fine b/c we stored something in it before - let queue = queue_rc.as_ref().unwrap(); - - if queue.push(payload).is_err() { - log::error!("BLE TX queue is full"); - } - } - }); -} - /// Create an advertiser to use to connect to a BLE Central, and wait for it to connect. async fn advertise<'values, 'server, C: Controller>( name: &'values str, @@ -250,23 +223,20 @@ async fn gatt_events_task( Ok(()) } -async fn publishing_task(server: &Server<'_>, conn: &GattConnection<'_, '_, P>) { - critical_section::with(|cs| { - let value_ref = CLIENT_CONNECTED.borrow(cs); - let _ = value_ref.replace(true); - }); - +/// Example task to use the BLE notifier interface. +/// This task will notify the connected central of a counter value every 2 seconds. +/// It will also read the RSSI value every 2 seconds. +/// and will stop when the connection is closed by the central or an error occurs. +async fn custom_task(server: &Server<'_>, conn: &GattConnection<'_, '_, P>) { loop { embassy_time::Timer::after(embassy_time::Duration::from_millis(10)).await; let mut new_data = None; critical_section::with(|cs| { - let queue_rc = TX_DATA.borrow(cs).borrow(); - // unwrap is fine b/c we stored something in it before - let queue = queue_rc.as_ref().unwrap(); + let tx_data_ref = TX_DATA.borrow(cs); - if let Some(data) = queue.pop() { - new_data = Some(data); + if let Some(tx_data) = tx_data_ref.replace(None) { + new_data = Some(tx_data); } }); diff --git a/src/io.rs b/src/io.rs index 1241953..aeeab92 100644 --- a/src/io.rs +++ b/src/io.rs @@ -454,11 +454,11 @@ impl msg::RawMsgTx { } #[cfg(feature = "cam")] -impl From<&alloc::boxed::Box> +impl From> for msg::CamEvent { fn from( - value: &alloc::boxed::Box, + value: alloc::boxed::Box, ) -> Self { use c_its_parser::standards::cam_1_4_1::cam_pdu_descriptions; @@ -469,14 +469,12 @@ impl From<&alloc::boxed::Box None, }); - let vehicle_data = match &value.cam.cam_parameters.high_frequency_container { + let vehicle_data = match value.cam.cam_parameters.high_frequency_container { cam_pdu_descriptions::HighFrequencyContainer::basicVehicleContainerHighFrequency( basic_vehicle_container_high_frequency, ) => Some(basic_vehicle_container_high_frequency.into()), @@ -502,8 +500,8 @@ impl From<&alloc::boxed::Box for msg::VehicleContainer { - fn from(value: &c_its_parser::standards::cam_1_4_1::cam_pdu_descriptions::BasicVehicleContainerHighFrequency) -> Self { +impl From for msg::VehicleContainer { + fn from(value: c_its_parser::standards::cam_1_4_1::cam_pdu_descriptions::BasicVehicleContainerHighFrequency) -> Self { let heading_deg = if value.heading.heading_value.is_unavailable() { None } else { @@ -531,11 +529,11 @@ impl From<&c_its_parser::standards::cam_1_4_1::cam_pdu_descriptions::BasicVehicl } #[cfg(feature = "denm")] -impl From<&alloc::boxed::Box> +impl From> for msg::DenmEvent { fn from( - value: &alloc::boxed::Box, + value: alloc::boxed::Box, ) -> Self { let denm_mgmt = &value.denm.management; @@ -554,8 +552,7 @@ impl From<&alloc::boxed::Box ! { transport: _, ref etsi, } => { - state.handle_mapem(etsi); + state.handle_mapem(&etsi); // Send data to BLE thread #[cfg(feature = "ble")] match io::msg::RawMsgRx::try_from(&msg) { Ok(data) => { - ble::update(ble::BleSendable::MapemRaw(data)); + critical_section::with(|cs| { + let ble_update_ref = ble::TX_DATA.borrow(cs); + ble_update_ref + .replace(Some(ble::BleSendable::MapemRaw(data))); + }); } Err(err) => warn!("Failed to create RawMsgRx: {err}"), } @@ -526,14 +530,18 @@ async fn main(spawner: Spawner) -> ! { ref etsi, } => { if state.initialized() { - state.handle_spatem(etsi); + state.handle_spatem(&etsi); } // Send data to BLE thread #[cfg(feature = "ble")] match io::msg::RawMsgRx::try_from(&msg) { Ok(data) => { - ble::update(ble::BleSendable::SpatemRaw(data)); + critical_section::with(|cs| { + let ble_update_ref = ble::TX_DATA.borrow(cs); + ble_update_ref + .replace(Some(ble::BleSendable::SpatemRaw(data))); + }); } Err(err) => warn!("Failed to create RawMsgRx: {err}"), } @@ -543,48 +551,37 @@ async fn main(spawner: Spawner) -> ! { ItsMessage::Cam { geonetworking: _, transport: _, - ref etsi, + etsi, } => { #[cfg(feature = "cam")] - applogic::cam::handle_cam(etsi); + applogic::cam::handle_cam(&etsi); // Send data to BLE thread #[cfg(all(feature = "ble", feature = "cam"))] - { - ble::update(ble::BleSendable::Cam(etsi.into())); + critical_section::with(|cs| { + let ble_update_ref = ble::TX_DATA.borrow(cs); + ble_update_ref.replace(Some(ble::BleSendable::Cam(etsi.into()))); + }); - // raw data only when it's a full CAM - if etsi.cam.cam_parameters.low_frequency_container.is_some() { - match io::msg::RawMsgRx::try_from(&msg) { - Ok(data) => { - ble::update(ble::BleSendable::CamRaw(data)); - } - Err(err) => warn!("Failed to create RawMsgRx: {err}"), - } - } - } + // TODO: Send Raw message, but only when it has high-freq container } #[cfg(feature = "denm")] ItsMessage::DenmV2 { geonetworking: _, transport: _, - ref etsi, + etsi, } => { - applogic::denm::handle_denm(etsi); + applogic::denm::handle_denm(&etsi); // Send data to BLE thread #[cfg(feature = "ble")] - { - ble::update(ble::BleSendable::Denm(etsi.into())); + critical_section::with(|cs| { + let ble_update_ref = ble::TX_DATA.borrow(cs); + ble_update_ref.replace(Some(ble::BleSendable::Denm(etsi.into()))); + }); - match io::msg::RawMsgRx::try_from(&msg) { - Ok(data) => { - ble::update(ble::BleSendable::DenmRaw(data)); - } - Err(err) => warn!("Failed to create RawMsgRx: {err}"), - } - } + // TODO: Send Raw message } #[cfg(feature = "denm")] ItsMessage::DenmV1 {