diff --git a/examples/ble_start_stop.rs b/examples/ble_start_stop.rs new file mode 100644 index 0000000..9662bc6 --- /dev/null +++ b/examples/ble_start_stop.rs @@ -0,0 +1,107 @@ +#![no_std] +#![no_main] + +extern crate alloc; + +use esp32_nimble::{uuid128, BLEDevice, NimbleProperties}; +use esp_idf_hal::peripherals::Peripherals; +use esp_idf_hal::uart::*; +use esp_idf_hal::units::Hertz; +use esp_idf_hal::{delay::*, gpio}; +use esp_idf_sys as _; + +#[no_mangle] +fn main() { + esp_idf_sys::link_patches(); + esp_idf_svc::log::EspLogger::initialize_default(); + + let peripherals = Peripherals::take().unwrap(); + let config = config::Config::new().baudrate(Hertz(115_200)); + let uart = UartDriver::new( + peripherals.uart0, + peripherals.pins.gpio1, + peripherals.pins.gpio3, + Option::::None, + Option::::None, + &config, + ) + .unwrap(); + + let ble_device = BLEDevice::take(); + + let server = ble_device.get_server(); + server.on_connect(|server, desc| { + ::log::info!("Client connected"); + + server + .update_conn_params(desc.conn_handle, 24, 48, 0, 60) + .unwrap(); + + ::log::info!("Multi-connect support: start advertising"); + ble_device.get_advertising().start().unwrap(); + }); + let service = server.create_service(uuid128!("fafafafa-fafa-fafa-fafa-fafafafafafa")); + + // A static characteristic. + let static_characteristic = service.lock().create_characteristic( + uuid128!("d4e0e0d0-1a2b-11e9-ab14-d663bd873d93"), + NimbleProperties::READ, + ); + static_characteristic + .lock() + .set_value("Hello, world!".as_bytes()); + + // A characteristic that notifies every second. + let notifying_characteristic = service.lock().create_characteristic( + uuid128!("a3c87500-8ed3-4bdf-8a39-a01bebede295"), + NimbleProperties::READ | NimbleProperties::NOTIFY, + ); + notifying_characteristic.lock().set_value(b"Initial value."); + + // A writable characteristic. + let writable_characteristic = service.lock().create_characteristic( + uuid128!("3c9a3f00-8ed3-4bdf-8a39-a01bebede295"), + NimbleProperties::READ | NimbleProperties::WRITE, + ); + writable_characteristic + .lock() + .on_read(move |_, _| { + ::log::info!("Read from writable characteristic."); + }) + .on_write(move |args| { + ::log::info!("Wrote to writable characteristic: {:?}", args.recv_data); + }); + + let ble_advertising = ble_device.get_advertising(); + ble_advertising + .name("ESP32-GATT-Server") + .add_service_uuid(uuid128!("fafafafa-fafa-fafa-fafa-fafafafafafa")); + + ble_advertising.start().unwrap(); + + let mut buf = [0_u8; 10]; + let mut initialized = true; + loop { + esp_idf_hal::delay::FreeRtos::delay_ms(1000); + let len = uart.read(&mut buf, NON_BLOCK).unwrap(); + if (buf[..len]).contains(&b's') { + if initialized { + ::log::info!("stop BLE"); + BLEDevice::deinit(); + } else { + ::log::info!("start BLE"); + BLEDevice::init(); + } + initialized = !initialized; + } + } +} + +#[panic_handler] +#[allow(dead_code)] +fn panic(info: &core::panic::PanicInfo) -> ! { + ::log::error!("{:?}", info); + unsafe { + esp_idf_sys::abort(); + } +} diff --git a/src/ble_device.rs b/src/ble_device.rs index 6f327c9..96931a6 100644 --- a/src/ble_device.rs +++ b/src/ble_device.rs @@ -27,6 +27,7 @@ pub static mut BLE_SERVER: Lazy = Lazy::new(|| unsafe { static mut BLE_ADVERTISING: Lazy = Lazy::new(BLEAdvertising::new); pub static mut OWN_ADDR_TYPE: u8 = esp_idf_sys::BLE_OWN_ADDR_PUBLIC as _; +static mut INITIALIZED: bool = false; static mut SYNCED: bool = false; pub struct BLEDevice { @@ -34,46 +35,50 @@ pub struct BLEDevice { } impl BLEDevice { - fn init() { + pub fn init() { // NVS initialisation. unsafe { - let result = esp_idf_sys::nvs_flash_init(); - if result == esp_idf_sys::ESP_ERR_NVS_NO_FREE_PAGES - || result == esp_idf_sys::ESP_ERR_NVS_NEW_VERSION_FOUND - { - ::log::warn!("NVS initialisation failed. Erasing NVS."); - esp_nofail!(esp_idf_sys::nvs_flash_erase()); - esp_nofail!(esp_idf_sys::nvs_flash_init()); - } + if !INITIALIZED { + let result = esp_idf_sys::nvs_flash_init(); + if result == esp_idf_sys::ESP_ERR_NVS_NO_FREE_PAGES + || result == esp_idf_sys::ESP_ERR_NVS_NEW_VERSION_FOUND + { + ::log::warn!("NVS initialisation failed. Erasing NVS."); + esp_nofail!(esp_idf_sys::nvs_flash_erase()); + esp_nofail!(esp_idf_sys::nvs_flash_init()); + } - esp_nofail!(esp_idf_sys::esp_bt_controller_mem_release( - esp_idf_sys::esp_bt_mode_t_ESP_BT_MODE_CLASSIC_BT - )); + esp_nofail!(esp_idf_sys::esp_bt_controller_mem_release( + esp_idf_sys::esp_bt_mode_t_ESP_BT_MODE_CLASSIC_BT + )); - #[cfg(esp_idf_version_major = "4")] - esp_nofail!(esp_idf_sys::esp_nimble_hci_and_controller_init()); + #[cfg(esp_idf_version_major = "4")] + esp_nofail!(esp_idf_sys::esp_nimble_hci_and_controller_init()); - esp_idf_sys::nimble_port_init(); + esp_idf_sys::nimble_port_init(); - esp_idf_sys::ble_hs_cfg.sync_cb = Some(Self::on_sync); - esp_idf_sys::ble_hs_cfg.reset_cb = Some(Self::on_reset); + esp_idf_sys::ble_hs_cfg.sync_cb = Some(Self::on_sync); + esp_idf_sys::ble_hs_cfg.reset_cb = Some(Self::on_reset); - // Set initial security capabilities - esp_idf_sys::ble_hs_cfg.sm_io_cap = esp_idf_sys::BLE_HS_IO_NO_INPUT_OUTPUT as _; - esp_idf_sys::ble_hs_cfg.set_sm_bonding(0); - esp_idf_sys::ble_hs_cfg.set_sm_mitm(0); - esp_idf_sys::ble_hs_cfg.set_sm_sc(1); - esp_idf_sys::ble_hs_cfg.sm_our_key_dist = 1; - esp_idf_sys::ble_hs_cfg.sm_their_key_dist = 3; - esp_idf_sys::ble_hs_cfg.store_status_cb = Some(esp_idf_sys::ble_store_util_status_rr); + // Set initial security capabilities + esp_idf_sys::ble_hs_cfg.sm_io_cap = esp_idf_sys::BLE_HS_IO_NO_INPUT_OUTPUT as _; + esp_idf_sys::ble_hs_cfg.set_sm_bonding(0); + esp_idf_sys::ble_hs_cfg.set_sm_mitm(0); + esp_idf_sys::ble_hs_cfg.set_sm_sc(1); + esp_idf_sys::ble_hs_cfg.sm_our_key_dist = 1; + esp_idf_sys::ble_hs_cfg.sm_their_key_dist = 3; + esp_idf_sys::ble_hs_cfg.store_status_cb = Some(esp_idf_sys::ble_store_util_status_rr); - ble_store_config_init(); + ble_store_config_init(); - esp_idf_sys::nimble_port_freertos_init(Some(Self::blecent_host_task)); + esp_idf_sys::nimble_port_freertos_init(Some(Self::blecent_host_task)); + } while !SYNCED { esp_idf_sys::vPortYield(); } + + INITIALIZED = true; } } @@ -96,6 +101,7 @@ impl BLEDevice { ); } } + INITIALIZED = false; SYNCED = false; } };