Watch
0
0
Fork
You've already forked esp32-c_its-companion
0

WIP BLE: Add "service change attribute"

TODO: doesn't work yet
See https://github.com/embassy-rs/trouble/issues/180 and maybe https://github.com/embassy-rs/trouble/issues/515
This commit is contained in:
Jannik Beyerstedt 2026-08-18 17:11:31 +02:00
commit a921ebd434
3 changed files with 25 additions and 9 deletions

View file

@ -57,7 +57,7 @@ screen = ["dep:mipidsi", "dep:embedded-graphics", "dep:embedded-hal-bus", "dep:p
# enable I/O via UART
uart = ["_uart", "_gnss"]
# enable I/O via BLE
ble = ["_gnss", "denm"]
ble = ["_gnss"]
# internal feature, that any UART I/O is enabled
_uart = []

View file

@ -57,9 +57,7 @@ Enable UART I/O protocol according to [docs/uart-protocol.md](./docs/uart-protoc
### BLE
Enable BLE I/O protocol according to [docs/ble-protocol.md](./docs/ble-protocol.md).
Will enable `denm` feature, but also enabling `cam` is recommended for full functionality.
Note: Raw message reception is currently not implemented!
Enabling `denm` feature or `cam` feature is recommended, otherwise no data will be received.
## Usage

View file

@ -41,9 +41,16 @@ pub enum BleSendable {
#[gatt_server]
struct Server {
generic: Generic,
c_its_events: CITSEvents,
}
#[gatt_service(uuid = "1801")]
pub(crate) struct Generic {
#[characteristic(uuid = characteristic::SERVICE_CHANGED, indicate, read, value = 0x0100FFFF)]
service_changed: u32,
}
#[gatt_service(uuid = "c0b70000-d4f4-4000-ada8-f99a02ee315c")]
struct CITSEvents {
#[descriptor(uuid = descriptors::MEASUREMENT_DESCRIPTION, name = "Position", read, value = "PositionState proto msg", type = &'static str)]
@ -136,13 +143,20 @@ pub async fn run(
);
let server = Server::new_with_config(GapConfig::Peripheral(PeripheralConfig {
name: "ESP32 C-ITS",
appearance: &appearance::UNKNOWN,
appearance: &appearance::UNKNOWN, // TODO MESH_DEVICE?? outdoor_sports_activity::LOCATION_AND_NAVIGATION_DISPLAY
}))
.unwrap();
let handle_start = 0x0100_u16; // little-endian
let handle_end = 0xFFFF_u16;
let concatenated: u32 = ((handle_start as u32) << 16) | handle_end as u32;
info!("Concatenated: {concatenated:?}");
let test = server.set(&server.generic.service_changed, &concatenated);
info!("We were able to set service changed? {test:?}");
let _ = embassy_futures::join::join(ble_task(runner), async {
loop {
match advertise("ESP32 C-ITS", &mut peripheral, &server).await {
match advertise(&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);
@ -157,7 +171,7 @@ pub async fn run(
});
}
Err(e) => {
panic!("BLE ADV: fatal error {e:?}");
panic!("BLE ADV: fatal error: {e:?}");
}
}
}
@ -182,15 +196,19 @@ pub fn update(payload: BleSendable) {
/// 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; 35];
let service_uuid = Uuid::from(0xc0b70000d4f44000ada8f99a02ee315cu128)
.as_raw()
.try_into()
.unwrap();
let len = AdStructure::encode_slice(
&[
AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED),
AdStructure::CompleteLocalName(name.as_bytes()),
AdStructure::ServiceUuids128(&[service_uuid]),
AdStructure::ServiceUuids16(&[service::GATT.to_le_bytes()]),
],
&mut advertiser_data[..],
)?;