Closed Gibbz closed 1 month ago
I think i found what I need here to make an updater task: https://github.com/embassy-rs/nrf-softdevice/blob/master/examples/src/bin/ble_bas_peripheral_notify.rs#L169
I'm not having much luck setting up my code like the example. I need access to sd, however it is consumed by the connection. Ive got the following code at the end of my main loop:
let conn: Connection = unwrap!(peripheral::advertise_connectable(sd, adv, &config).await); // <- sd is consumed here
info!("advertising done!");
let update_fut = update_task(&server, &conn);
let gatt_fut = gatt_server::run(&conn, &server, |_| {});
pin_mut!(update_fut, gatt_fut);
let _ = match select(update_fut, gatt_fut).await {
Either::Left((_, _)) => {
info!("BLE update task encountered an error and stopped!")
}
Either::Right((e, _)) => {
info!("gatt_server run exited with error: {:?}", e);
}
};
And my update function:
// update task
async fn update_task<'a>(server: &'a Server, connection: &'a Connection) {
let mut sub_throttle_in = signals::THROTTLE_IN.subscriber().unwrap();
loop {
let val = sub_throttle_in.next_message_pure().await;
info!("ble pudate task throttle: {}", val);
let t = server.data.throttle_input_voltage_set(&sd, val); // <- function requires sd, which we cant use
match server.data.throttle_input_voltage_notify(connection, val) {
Ok(_) => info!("notified client"),
Err(_) => unwrap!(server.data.throttle_input_voltage_set(&sd, val)), // <- function requires sd, which we cant use
};
}
}
Edit: ive noticed gatt_server::set_value(sd, self.throttle_input_voltage, &split)
does not even use the sd reference in the code... Is there a way to pass null to this as its not even used?
Also I noticed in this example that its setup with a macro, so there must be some way I can copy the macro to get this working:
// Try and notify the connected client of the new ADC value.
match server.bas.battery_level_notify(connection, &adc_raw_value) {
Ok(_) => info!("Battery adc_raw_value: {=i16}", &adc_raw_value),
Err(_) => unwrap!(server.bas.battery_level_set(&adc_raw_value)),
};
//.... SNIP ....
#[nrf_softdevice::gatt_service(uuid = "180f")] // <- how is this macro setting up server.bas.battery_level_set(&adc_raw_value) ??
struct BatteryService {
#[characteristic(uuid = "2a19", read, notify)]
battery_level: i16,
}
Ive kind of got this working with a bit of hacking around...
I want to write and notify values on the ble server using pubsub channels. Ive tried storing the softdevice and connection objects. And ive tried setting up a new subtask. Both ways have not worked. Im happy for either the bluetooth to be subscribed. Or for my objects to access a write/notify function in the softdevice.
It looks like the gattserver consumes the softdevice and connection references. So I cannot share them or use them.
Any ideas how I can get this working?