From 164bc16e88241c61e9310d335535185a548ad55e Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Fri, 3 Oct 2025 00:06:50 +0200 Subject: [PATCH] Make ble_gatt_server.rs work with the nRF552 DK --- Cargo.lock | 2 +- src/bin/ble_gatt_server.rs | 192 ++++++++++++++++++------------------- 2 files changed, 96 insertions(+), 98 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f56e827..5e108ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -734,7 +734,7 @@ dependencies = [ "heapless", "nrf-softdevice-macro", "nrf-softdevice-s112", - "nrf52810-pac", + "nrf52832-pac", "num_enum", ] diff --git a/src/bin/ble_gatt_server.rs b/src/bin/ble_gatt_server.rs index b86d33a..b7536c4 100644 --- a/src/bin/ble_gatt_server.rs +++ b/src/bin/ble_gatt_server.rs @@ -61,102 +61,100 @@ async fn main(spawner: Spawner) { let mut led = Output::new(p.P0_18, Level::Low, OutputDrive::Standard); led.set_high(); - info!("Hello World!"); + let config = nrf_softdevice::Config { + clock: Some(raw::nrf_clock_lf_cfg_t { + source: raw::NRF_CLOCK_LF_SRC_RC as u8, + rc_ctiv: 16, + rc_temp_ctiv: 2, + accuracy: raw::NRF_CLOCK_LF_ACCURACY_500_PPM as u8, + }), + conn_gap: Some(raw::ble_gap_conn_cfg_t { + conn_count: 1, + event_length: 24, + }), + conn_gatt: Some(raw::ble_gatt_conn_cfg_t { att_mtu: 256 }), + gatts_attr_tab_size: Some(raw::ble_gatts_cfg_attr_tab_size_t { + attr_tab_size: raw::BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, + }), + gap_role_count: Some(raw::ble_gap_cfg_role_count_t { + adv_set_count: 1, + periph_role_count: 1, + // central_role_count: 3, + // central_sec_count: 0, + // _bitfield_1: raw::ble_gap_cfg_role_count_t::new_bitfield_1(0), + }), + gap_device_name: Some(raw::ble_gap_cfg_device_name_t { + p_value: b"HelloRust" as *const u8 as _, + current_len: 9, + max_len: 9, + write_perm: unsafe { mem::zeroed() }, + _bitfield_1: raw::ble_gap_cfg_device_name_t::new_bitfield_1( + raw::BLE_GATTS_VLOC_STACK as u8, + ), + }), + ..Default::default() + }; - // let config = nrf_softdevice::Config { - // clock: Some(raw::nrf_clock_lf_cfg_t { - // source: raw::NRF_CLOCK_LF_SRC_RC as u8, - // rc_ctiv: 16, - // rc_temp_ctiv: 2, - // accuracy: raw::NRF_CLOCK_LF_ACCURACY_500_PPM as u8, - // }), - // conn_gap: Some(raw::ble_gap_conn_cfg_t { - // conn_count: 1, - // event_length: 24, - // }), - // conn_gatt: Some(raw::ble_gatt_conn_cfg_t { att_mtu: 256 }), - // gatts_attr_tab_size: Some(raw::ble_gatts_cfg_attr_tab_size_t { - // attr_tab_size: raw::BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, - // }), - // gap_role_count: Some(raw::ble_gap_cfg_role_count_t { - // adv_set_count: 1, - // periph_role_count: 1, - // // central_role_count: 3, - // // central_sec_count: 0, - // // _bitfield_1: raw::ble_gap_cfg_role_count_t::new_bitfield_1(0), - // }), - // gap_device_name: Some(raw::ble_gap_cfg_device_name_t { - // p_value: b"HelloRust" as *const u8 as _, - // current_len: 9, - // max_len: 9, - // write_perm: unsafe { mem::zeroed() }, - // _bitfield_1: raw::ble_gap_cfg_device_name_t::new_bitfield_1( - // raw::BLE_GATTS_VLOC_STACK as u8, - // ), - // }), - // ..Default::default() - // }; - // - // let sd = Softdevice::enable(&config); - // let server = unwrap!(Server::new(sd)); - // unwrap!(spawner.spawn(softdevice_task(sd))); - // - // static ADV_DATA: LegacyAdvertisementPayload = LegacyAdvertisementBuilder::new() - // .flags(&[Flag::GeneralDiscovery, Flag::LE_Only]) - // .services_16(ServiceList::Complete, &[ServiceUuid16::BATTERY]) - // .full_name("HelloRust") - // .build(); - // - // static SCAN_DATA: LegacyAdvertisementPayload = LegacyAdvertisementBuilder::new() - // .services_128( - // ServiceList::Complete, - // &[0x9e7312e0_2354_11eb_9f10_fbc30a62cf38_u128.to_le_bytes()], - // ) - // .build(); - // - // loop { - // info!("Creating config"); - // let config = peripheral::Config::default(); - // info!("Creating adv object"); - // let adv = peripheral::ConnectableAdvertisement::ScannableUndirected { - // adv_data: &ADV_DATA, - // scan_data: &SCAN_DATA, - // }; - // info!("Starting advertising"); - // let conn = unwrap!(peripheral::advertise_connectable(sd, adv, &config).await); - // - // info!("advertising done!"); - // - // // Run the GATT server on the connection. This returns when the connection gets disconnected. - // // - // // Event enums (ServerEvent's) are generated by nrf_softdevice::gatt_server - // // proc macro when applied to the Server struct above - // let e = gatt_server::run(&conn, &server, |e| match e { - // ServerEvent::Bas(e) => match e { - // BatteryServiceEvent::BatteryLevelCccdWrite { notifications } => { - // info!("battery notifications: {}", notifications) - // } - // }, - // ServerEvent::Foo(e) => match e { - // FooServiceEvent::FooWrite(val) => { - // info!("wrote foo: {}", val); - // if let Err(e) = server.foo.foo_notify(&conn, &(val + 1)) { - // info!("send notification error: {:?}", e); - // } - // } - // FooServiceEvent::FooCccdWrite { - // indications, - // notifications, - // } => { - // info!( - // "foo indications: {}, notifications: {}", - // indications, notifications - // ) - // } - // }, - // }) - // .await; - // - // info!("gatt_server run exited with error: {:?}", e); - // } + let sd = Softdevice::enable(&config); + let server = unwrap!(Server::new(sd)); + unwrap!(spawner.spawn(softdevice_task(sd))); + + static ADV_DATA: LegacyAdvertisementPayload = LegacyAdvertisementBuilder::new() + .flags(&[Flag::GeneralDiscovery, Flag::LE_Only]) + .services_16(ServiceList::Complete, &[ServiceUuid16::BATTERY]) + .full_name("HelloRust") + .build(); + + static SCAN_DATA: LegacyAdvertisementPayload = LegacyAdvertisementBuilder::new() + .services_128( + ServiceList::Complete, + &[0x9e7312e0_2354_11eb_9f10_fbc30a62cf38_u128.to_le_bytes()], + ) + .build(); + + loop { + info!("Creating config"); + let config = peripheral::Config::default(); + info!("Creating adv object"); + let adv = peripheral::ConnectableAdvertisement::ScannableUndirected { + adv_data: &ADV_DATA, + scan_data: &SCAN_DATA, + }; + info!("Starting advertising"); + let conn = unwrap!(peripheral::advertise_connectable(sd, adv, &config).await); + + info!("advertising done!"); + + // Run the GATT server on the connection. This returns when the connection gets disconnected. + // + // Event enums (ServerEvent's) are generated by nrf_softdevice::gatt_server + // proc macro when applied to the Server struct above + let e = gatt_server::run(&conn, &server, |e| match e { + ServerEvent::Bas(e) => match e { + BatteryServiceEvent::BatteryLevelCccdWrite { notifications } => { + info!("battery notifications: {}", notifications) + } + }, + ServerEvent::Foo(e) => match e { + FooServiceEvent::FooWrite(val) => { + info!("wrote foo: {}", val); + if let Err(e) = server.foo.foo_notify(&conn, &(val + 1)) { + info!("send notification error: {:?}", e); + } + } + FooServiceEvent::FooCccdWrite { + indications, + notifications, + } => { + info!( + "foo indications: {}, notifications: {}", + indications, notifications + ) + } + }, + }) + .await; + + info!("gatt_server run exited with error: {:?}", e); + } }