eculocate

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit a729199926b82e9102e0998998893bc56d2c384a
parent 13b0868488f8137ad1bd059b876c404a1c8fef7e
Author: Daniel Barlow <dan@telent.net>
Date:   Sun,  1 Feb 2026 15:27:30 +0000

PoC BLE support

It advertises, and it enumerates some characteristics. None of them
are hooked up to anthing yet

Diffstat:
MCargo.lock | 373+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mecu-esp32/Cargo.toml | 5+++++
Mecu-esp32/src/main.rs | 11++++++++---
Aecu-esp32/src/wibble.rs | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 595 insertions(+), 3 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -3,6 +3,17 @@ version = 4 [[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] name = "allocator-api2" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -27,6 +38,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] name = "base64" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -98,6 +115,15 @@ name = "btuuid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0acfef8a77a02866e04f7e2ad3f4c7b32d575696c49c4bbad742b4aecb8e4a3" +dependencies = [ + "uuid", +] + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytemuck" @@ -118,6 +144,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "cmac" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa" +dependencies = [ + "cipher", + "dbl", + "digest", +] + +[[package]] name = "const-default" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -130,6 +177,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] +name = "convert_case" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +dependencies = [ + "unicode-segmentation", +] + +[[package]] name = "cpufeatures" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -145,6 +201,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] name = "crypto-common" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -285,6 +353,15 @@ dependencies = [ ] [[package]] +name = "dbl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9" +dependencies = [ + "generic-array", +] + +[[package]] name = "delegate" version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -313,6 +390,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -362,6 +440,7 @@ dependencies = [ "rand_core 0.6.4", "smoltcp", "static_cell", + "trouble-host", ] [[package]] @@ -393,6 +472,25 @@ dependencies = [ ] [[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] name = "embassy-embedded-hal" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1037,6 +1135,16 @@ dependencies = [ ] [[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] name = "fiat-crypto" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1064,6 +1172,30 @@ dependencies = [ ] [[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] name = "futures-core" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1080,6 +1212,12 @@ dependencies = [ ] [[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] name = "futures-sink" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1098,6 +1236,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", + "futures-sink", "futures-task", "pin-project-lite", "pin-utils", @@ -1117,6 +1256,18 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", ] [[package]] @@ -1166,6 +1317,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1191,6 +1360,15 @@ dependencies = [ ] [[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] name = "instability" version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1234,6 +1412,16 @@ dependencies = [ ] [[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] name = "libc" version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1314,6 +1502,22 @@ dependencies = [ ] [[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "elliptic-curve", + "primeorder", +] + +[[package]] name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1378,6 +1582,24 @@ dependencies = [ ] [[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] name = "proc-macro-crate" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1405,6 +1627,25 @@ dependencies = [ ] [[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1515,6 +1756,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] name = "semver" version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1741,6 +1995,44 @@ dependencies = [ ] [[package]] +name = "trouble-host" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2881b4859001fe1f48445145cda5149deac9110b1d707ec0a251b7ff6d8bdfa4" +dependencies = [ + "aes", + "bt-hci", + "cmac", + "embassy-futures", + "embassy-sync 0.7.2", + "embassy-time", + "embedded-io 0.6.1", + "futures", + "heapless 0.9.2", + "p256", + "rand", + "rand_chacha", + "rand_core 0.6.4", + "static_cell", + "trouble-host-macros", + "zerocopy", +] + +[[package]] +name = "trouble-host-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcb85bec3a8393c22ca1a7c25c82c2d33689ab412f3487c492fd01a033ede7c2" +dependencies = [ + "convert_case", + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.114", + "uuid", +] + +[[package]] name = "typenum" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1759,6 +2051,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] name = "unicode-width" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1771,6 +2069,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] +name = "uuid" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] name = "vcell" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1789,6 +2097,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] +name = "wasm-bindgen" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.114", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + +[[package]] name = "winapi-util" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1853,6 +2206,26 @@ dependencies = [ ] [[package]] +name = "zerocopy" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7456cf00f0685ad319c5b1693f291a650eaf345e941d082fc4e03df8a03996ac" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1328722bbf2115db7e19d69ebcc15e795719e2d66b60827c6a69a117365e37a0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/ecu-esp32/Cargo.toml b/ecu-esp32/Cargo.toml @@ -72,3 +72,8 @@ ed25519-dalek = { version = "2", default-features = false, features = ["alloc"] rand_core = "0.6" nb = "1.1.0" hashbrown = "0.16.1" +trouble-host = { version = "0.5.1", default-features = false, features = [ + "peripheral", "gatt", "derive", "security", "default-packet-pool", + "default-packet-pool-mtu-64", + "dev-disable-csprng-seed-requirement" # !!!! +]} diff --git a/ecu-esp32/src/main.rs b/ecu-esp32/src/main.rs @@ -8,12 +8,15 @@ use esp_backtrace as _; use esp_println as _; +use esp_alloc as _; + pub mod ecu; pub mod wifi; pub mod mdns; pub mod streamer; pub mod ota; +pub mod wibble; use esp_hal::{ timer::timg::TimerGroup, @@ -21,7 +24,7 @@ use esp_hal::{ }; use embassy_executor::Spawner; -use embassy_futures::join::join; +use embassy_futures::join::join3; use embassy_time::Timer; use esp_radio::Controller; @@ -58,7 +61,7 @@ async fn main(s : Spawner) { let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); - esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 66320); + esp_alloc::heap_allocator!(size: 92 * 1024); // handwaving: we need the timer to schedule tasks for the rtos, // and we need the rtos so that the ble works (assumption: @@ -80,14 +83,16 @@ async fn main(s : Spawner) { let flasher = Flasher::new(peripherals.FLASH, peripherals.SHA); - join( let esp_radio_ctrl = // esp_radio::init().expect("esp_radio init failed"); &*mk_static!(Controller<'static>, esp_radio::init().unwrap()); + + join3( crate::wifi::start_wifi(&s, esp_radio_ctrl, flasher, peripherals.WIFI, &mut ecu), + wibble::run_ble(&esp_radio_ctrl, peripherals.BT), async { loop { Timer::after_millis(1000).await; diff --git a/ecu-esp32/src/wibble.rs b/ecu-esp32/src/wibble.rs @@ -0,0 +1,209 @@ +use embassy_time::Timer; +use trouble_host::prelude::*; +use esp_radio::ble::controller::BleConnector; +use esp_radio::Controller as RadioController; +use log::{warn,info}; +use embassy_futures::join::join; +use embassy_futures::select::select; + +use alloc::string::String; + +/// Max number of connections +const CONNECTIONS_MAX: usize = 1; + +/// Max number of L2CAP channels. +// XXX why not 0? +const L2CAP_CHANNELS_MAX: usize = 2; // Signal + att + +// GATT Server definition +#[gatt_server] +struct Server { + wifi_provisioning_service: WifiProvisioningService, +} + + +#[gatt_service(uuid = "76be25c2-0000-44fc-a97c-bcb56c69c926")] +struct WifiProvisioningService { + #[characteristic(uuid = "76be25c2-0801-44fc-a97c-bcb56c69c926", read, notify, value = 0)] + connection_state: u8, + + #[characteristic(uuid = "76be25c2-0802-44fc-a97c-bcb56c69c926", read, notify, value = 0)] + max_network_index: u8, + + #[characteristic(uuid = "76be25c2-0803-44fc-a97c-bcb56c69c926", write, value = 0)] + current_network_index: u8, + + // for arrays > 32 we must supply a default value : see + // https://github.com/embassy-rs/trouble/issues/320 + #[characteristic(uuid = "76be25c2-0804-44fc-a97c-bcb56c69c926", + value = [0; 40], + read, notify)] + current_network: [u8; 40], + + #[characteristic(uuid = "76be25c2-0805-44fc-a97c-bcb56c69c926", + value = [0; 64], + write)] + secret: [u8; 64] +} + + +pub async fn run_ble(radio_init: &RadioController<'static>, + peripheral: esp_hal::peripherals::BT<'_>) { + // let radio_init = esp_radio::init().expect("Failed to initialize Wi-Fi/BLE controller"); + let connector = BleConnector::new(&radio_init, peripheral, Default::default()).expect("connector"); + let controller: ExternalController<_, 20> = ExternalController::new(connector); + + // Using a fixed "random" address can be useful for testing. In real scenarios, one would + // use e.g. the MAC 6 byte array as the address (how to get that varies by the platform). + let address: Address = Address::random([0xff, 0x8f, 0x1a, 0x05, 0xe4, 0xff]); + info!("Our address = {:?}", address); + + let mut resources: HostResources<DefaultPacketPool, CONNECTIONS_MAX, L2CAP_CHANNELS_MAX> = HostResources::new(); + let stack = trouble_host::new(controller, &mut resources).set_random_address(address); + let Host { + mut peripheral, runner, .. + } = stack.build(); + + info!("Starting advertising and GATT service"); + let server = Server::new_with_config(GapConfig::Peripheral(PeripheralConfig { + name: "eculocate", + appearance: &appearance::power_device::GENERIC_POWER_DEVICE, + })) + .unwrap(); + + let _ = join( + ble_task(runner), + async { + loop { + match advertise("Eculocate", &mut peripheral, &server).await { + 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 = custom_task(&server, &conn, &stack); + // run until any task ends (usually because the connection has been closed), + // then return to advertising state. + select(a, b).await; + } + Err(e) => { + panic!("[adv] error: {:?}", e); + } + } + } + }) + .await; +} + +/// This is a background task that is required to run forever alongside any other BLE tasks. +/// +async fn ble_task<C: Controller, P: PacketPool>(mut runner: Runner<'_, C, P>) { + loop { + if let Err(e) = runner.run().await { + panic!("[ble_task] error: {:?}", e); + } + } +} + +/// Stream Events until the connection closes. +/// +/// This function will handle the GATT events and process them. +/// This is how we interact with read and write requests. +async fn gatt_events_task<P: PacketPool>(_server: &Server<'_>, conn: &GattConnection<'_, '_, P>) -> Result<(), Error> { + // let level = server.battery_service.level; + let reason = loop { + match conn.next().await { + GattConnectionEvent::Disconnected { reason } => break reason, + GattConnectionEvent::Gatt { event } => { + // match &event { + // // are these clauses important? they don't do anything + // // except log + // GattEvent::Read(event) => { + // if event.handle() == level.handle { + // let value = server.get(&level); + // info!("[gatt] Read Event to Level Characteristic: {:?}", value); + // } + // } + // GattEvent::Write(event) => { + // if event.handle() == level.handle { + // info!("[gatt] Write Event to Level Characteristic: {:?}", event.data()); + // } + // } + // _ => {} + // }; + // This step is also performed at drop(), but writing it explicitly is necessary + // in order to ensure reply is sent. + match event.accept() { + Ok(reply) => reply.send().await, + Err(e) => warn!("[gatt] error sending response: {:?}", e), + }; + } + _ => {} // ignore other Gatt Connection Events + } + }; + info!("[gatt] disconnected: {:?}", reason); + Ok(()) +} + +/// 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, + peripheral: &mut Peripheral<'values, C, DefaultPacketPool>, + server: &'server Server<'values>, +) -> Result<GattConnection<'values, 'server, DefaultPacketPool>, BleHostError<C::Error>> { + let mut advertiser_data = [0; 31]; + let len = AdStructure::encode_slice( + &[ + AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED), + AdStructure::ServiceUuids16(&[[0x0f, 0x18]]), + AdStructure::CompleteLocalName(name.as_bytes()), + ], + &mut advertiser_data[..], + )?; + let advertiser = peripheral + .advertise( + &Default::default(), + Advertisement::ConnectableScannableUndirected { + adv_data: &advertiser_data[..len], + scan_data: &[], + }, + ) + .await?; + info!("[adv] advertising"); + let conn = advertiser.accept().await?.with_attribute_server(server)?; + info!("[adv] connection established"); + Ok(conn) +} + +async fn custom_task<C: Controller, P: PacketPool>( + _server: &Server<'_>, + conn: &GattConnection<'_, '_, P>, + stack: &Stack<'_, C, P>, +) { + // let mut tick: u8 = 0; + // let level = server.battery_service.level; + // let rpm = server.engine_speed_service.rpm; + loop { + // tick = tick.wrapping_add(1); + // info!("[custom_task] notifying connection of tick {}", tick); + + // // if the characteristic does not support notifications, + // // this would return an error. Use `set` instead, in that case. + // // See inline comments in trouble-host/src/attribute.rs around + // // line 631 + + // if level.notify(conn, &tick).await.is_err() { + // info!("[custom_task] error notifying connection"); + // break; + // }; + // read RSSI (Received Signal Strength Indicator) of the connection. + if let Ok(rssi) = conn.raw().rssi(stack).await { + info!("[custom_task] RSSI: {:?}", rssi); + } else { + info!("[custom_task] error getting RSSI"); + break; + }; + // let new_rpm = 1200 + 20 * i32::from(tick); + // rpm.notify(conn, &new_rpm).await.expect("failed to notify"); + + Timer::after_secs(2).await; + } +}