From 0e8fe21d0ab1162c8e570d63a7bc7fade91462cd Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Mon, 25 Nov 2024 14:08:18 +0200 Subject: [PATCH] Update NUS peripheral example to latest API changes Fixup for Trouble, embassy and nrf-sdc API changes. --- examples/apps/src/ble_nus_peripheral.rs | 89 ++++++++++++------- .../nrf-sdc/src/bin/ble_nus_peripheral.rs | 19 +--- 2 files changed, 60 insertions(+), 48 deletions(-) diff --git a/examples/apps/src/ble_nus_peripheral.rs b/examples/apps/src/ble_nus_peripheral.rs index 703e2089..f33871b9 100644 --- a/examples/apps/src/ble_nus_peripheral.rs +++ b/examples/apps/src/ble_nus_peripheral.rs @@ -1,5 +1,8 @@ /* Nordic Uart Service (NUS) peripheral example */ -use embassy_futures::join::join3; +use embassy_futures::{ + join::join3, + select::{select, Either}, +}; use embassy_time::{Duration, Timer}; use heapless::Vec; use trouble_host::prelude::*; @@ -13,15 +16,13 @@ const CONNECTIONS_MAX: usize = 1; /// Max number of L2CAP channels. const L2CAP_CHANNELS_MAX: usize = 2; // Signal + att -const MAX_ATTRIBUTES: usize = 32; - pub const MTU: usize = 120; // Aligned to 4 bytes + 3 bytes for header pub const ATT_MTU: usize = MTU + 3; type Resources = HostResources; -// GATT Server +// GATT Server definition #[gatt_server] struct Server { nrf_uart: NrfUartService, @@ -52,10 +53,11 @@ where let server = Server::new_with_config( stack, GapConfig::Peripheral(PeripheralConfig { - name: "TrouBLE", + name: "TrouBLE NUS", appearance: &appearance::GENERIC_UNKNOWN, }), - ); + ) + .unwrap(); info!("Starting advertising and GATT service"); let _ = join3( @@ -70,33 +72,20 @@ async fn ble_task(mut runner: Runner<'_, C>) -> Result<(), BleHos runner.run().await } -async fn gatt_task(server: &Server<'_, C>) { - loop { - match server.next().await { - Ok(GattEvent::Write { handle, connection: _ }) => { - let _ = server.get(handle, |value| { - info!("[gatt] Write event on {:?}. Value written: {:?}", handle, value); - }); - } - Ok(GattEvent::Read { handle, connection: _ }) => { - info!("[gatt] Read event on {:?}", handle); - } - Err(e) => { - error!("[gatt] Error processing GATT events: {:?}", e); - } - } - } +async fn gatt_task(server: &Server<'_, '_, C>) -> Result<(), BleHostError> { + server.run().await } async fn advertise_task( mut peripheral: Peripheral<'_, C>, - server: &Server<'_, C>, + server: &Server<'_, '_, C>, ) -> Result<(), BleHostError> { let mut adv_data = [0; 31]; AdStructure::encode_slice( &[ AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED), - AdStructure::CompleteLocalName(b"Trouble NRF UART (NUS) Service"), + AdStructure::ServiceUuids16(&[Uuid::Uuid16([0x0f, 0x18])]), + AdStructure::CompleteLocalName(b"TrouBLE NUS"), ], &mut adv_data[..], )?; @@ -113,17 +102,51 @@ async fn advertise_task( .await?; let conn = advertiser.accept().await?; - /* TODO: Implement "echo" and push rx bytes back to tx? */ - // XXX: I have to manually "fix" the size from 123 -> 128 - let mut tx = [0; 128]; let mut tick: u8 = 0; + let mut buf = Vec::::from_slice(&[0; ATT_MTU]).unwrap(); + // Keep connection alive - while conn.is_connected() { - Timer::after(Duration::from_secs(2)).await; - tick = tick.wrapping_add(1); - tx[0] = tick; - info!("[adv] notifying connection of tick {}", tick); - let _ = server.notify(server.nrf_uart.tx, &conn, &tx[..]).await; + loop { + match select(conn.next(), Timer::after(Duration::from_secs(2))).await { + Either::First(event) => match event { + ConnectionEvent::Disconnected { reason } => { + info!("[adv] disconnected: {:?}", reason); + break; + } + ConnectionEvent::Gatt { event, .. } => match event { + GattEvent::Read { value_handle } => { + /* + if value_handle == server.nrf_uart.rx_buf.handle { + let value = server.get(&rx_buf).unwrap(); + info!("[gatt] Read Event to rx_buf Characteristic: {:?}", value.len()); + } else if value_handle == tx_buf.handle { + let value = server.get(&tx_buf).unwrap(); + info!("[gatt] Read Event to tx_buf Characteristic: {:?}", value.len()); + } + */ + defmt::info!("Read..."); + } + GattEvent::Write { value_handle } => { + /* + if value_handle == rx_buf.handle { + let value = server.get(&rx_buf).unwrap(); + info!("[gatt] Write Event to rx_buf Characteristic: {:?}", value.len()); + } else if value_handle == tx_buf.handle { + let value = server.get(&tx_buf).unwrap(); + info!("[gatt] Write Event to tx_buf Characteristic: {:?}", value.len()); + } + */ + defmt::info!("Write..."); + } + }, + }, + Either::Second(_) => { + tick = tick.wrapping_add(1); + info!("[adv] notifying connection of tick {}", tick); + buf[0] = tick; + let _ = server.notify(&server.nrf_uart.tx, &conn, &buf).await; + } + } } } } diff --git a/examples/nrf-sdc/src/bin/ble_nus_peripheral.rs b/examples/nrf-sdc/src/bin/ble_nus_peripheral.rs index f234efa1..a5defc12 100644 --- a/examples/nrf-sdc/src/bin/ble_nus_peripheral.rs +++ b/examples/nrf-sdc/src/bin/ble_nus_peripheral.rs @@ -4,7 +4,7 @@ use defmt::unwrap; use embassy_executor::Spawner; use embassy_nrf::peripherals::RNG; -use embassy_nrf::{bind_interrupts, pac, rng}; +use embassy_nrf::{bind_interrupts, rng}; use nrf_sdc::mpsl::MultiprotocolServiceLayer; use nrf_sdc::{self as sdc, mpsl}; use static_cell::StaticCell; @@ -41,18 +41,7 @@ fn build_sdc<'d, const N: usize>( #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_nrf::init(Default::default()); - let pac_p = pac::Peripherals::take().unwrap(); - - let mpsl_p = mpsl::Peripherals::new( - pac_p.CLOCK, - pac_p.RADIO, - p.RTC0, - p.TIMER0, - p.TEMP, - p.PPI_CH19, - p.PPI_CH30, - p.PPI_CH31, - ); + let mpsl_p = mpsl::Peripherals::new(p.RTC0, p.TIMER0, p.TEMP, p.PPI_CH19, p.PPI_CH30, p.PPI_CH31); let lfclk_cfg = mpsl::raw::mpsl_clock_lfclk_cfg_t { source: mpsl::raw::MPSL_CLOCK_LF_SRC_RC as u8, rc_ctiv: mpsl::raw::MPSL_RECOMMENDED_RC_CTIV as u8, @@ -65,8 +54,8 @@ async fn main(spawner: Spawner) { spawner.must_spawn(mpsl_task(&*mpsl)); let sdc_p = sdc::Peripherals::new( - pac_p.ECB, pac_p.AAR, p.PPI_CH17, p.PPI_CH18, p.PPI_CH20, p.PPI_CH21, p.PPI_CH22, p.PPI_CH23, p.PPI_CH24, - p.PPI_CH25, p.PPI_CH26, p.PPI_CH27, p.PPI_CH28, p.PPI_CH29, + p.PPI_CH17, p.PPI_CH18, p.PPI_CH20, p.PPI_CH21, p.PPI_CH22, p.PPI_CH23, p.PPI_CH24, p.PPI_CH25, p.PPI_CH26, + p.PPI_CH27, p.PPI_CH28, p.PPI_CH29, ); let mut rng = rng::Rng::new(p.RNG, Irqs);