-
Notifications
You must be signed in to change notification settings - Fork 246
Expand file tree
/
Copy pathtrouble_beacon.rs
More file actions
112 lines (95 loc) · 3.49 KB
/
Copy pathtrouble_beacon.rs
File metadata and controls
112 lines (95 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! Non-connectable BLE beacon using the Trouble host with ESP-IDF's controller.
//!
//! Enable the `trouble` and `embassy-time-driver` Cargo features and use a
//! controller-only ESP-IDF configuration such as
//! `.github/configs/sdkconfig.defaults.trouble`.
#![allow(unknown_lints)]
#![allow(unexpected_cfgs)]
#[cfg(all(
not(any(esp32s2, esp32p4)),
feature = "trouble",
esp_idf_bt_enabled,
esp_idf_bt_controller_only,
))]
fn main() -> anyhow::Result<()> {
example::main()
}
#[cfg(not(all(
not(any(esp32s2, esp32p4)),
feature = "trouble",
esp_idf_bt_enabled,
esp_idf_bt_controller_only,
)))]
fn main() -> anyhow::Result<()> {
panic!(
"This example requires the `trouble` feature and a controller-only configuration on a chip with a BLE radio"
);
}
#[cfg(all(
not(any(esp32s2, esp32p4)),
feature = "trouble",
esp_idf_bt_enabled,
esp_idf_bt_controller_only,
))]
mod example {
use anyhow::Result;
use bt_hci::controller::ExternalController;
use embassy_futures::select::{select, Either};
use trouble_host::prelude::*;
use esp_idf_svc::bt_controller::{Ble, EspBtController, EspVhciTransport};
use esp_idf_svc::hal::peripherals::Peripherals;
use esp_idf_svc::hal::task::block_on;
use esp_idf_svc::nvs::EspDefaultNvsPartition;
type Controller = ExternalController<EspVhciTransport<'static>, 10>;
pub fn main() -> Result<()> {
esp_idf_svc::sys::link_patches();
let _ = esp_idf_svc::hal::task::critical_section::link();
let _ = esp_idf_svc::timer::embassy_time_driver::link();
esp_idf_svc::log::EspLogger::initialize_default();
let peripherals = Peripherals::take()?;
// Keep NVS alive for ESP-IDF's PHY calibration data.
let _nvs = EspDefaultNvsPartition::take()?;
let controller = EspBtController::<Ble>::new(peripherals.modem)?;
let transport = EspVhciTransport::new(controller)?;
let controller = ExternalController::<_, 10>::new(transport);
block_on(run(controller));
Ok(())
}
async fn run(controller: Controller) {
let address = Address::random([0xff, 0x8f, 0x1a, 0x05, 0xe4, 0xff]);
let mut resources: HostResources<Controller, DefaultPacketPool, 0, 0, 1> =
HostResources::new();
let stack = trouble_host::new(controller, &mut resources)
.set_random_address(address)
.build();
let mut peripheral = stack.peripheral();
let mut runner = stack.runner();
let mut adv_data = [0; 31];
let len = AdStructure::encode_slice(
&[
AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED),
AdStructure::CompleteLocalName(b"ESP-IDF Trouble"),
],
&mut adv_data,
)
.unwrap();
log::info!("Starting Trouble beacon as {address:?}");
match select(runner.run(), async {
let _advertiser = peripheral
.advertise(
&AdvertisementParameters::default(),
Advertisement::NonconnectableNonscannableUndirected {
adv_data: &adv_data[..len],
},
)
.await
.unwrap();
core::future::pending::<()>().await;
})
.await
{
Either::First(result) => result.unwrap(),
Either::Second(()) => unreachable!("the advertising task never completes"),
}
}
}