distinguish between change and notify commands

This commit is contained in:
2024-08-24 10:06:17 -04:00
parent 7aab854a6b
commit 7c2d3df16b
2 changed files with 62 additions and 37 deletions

View File

@ -14,6 +14,9 @@ const BLE_MAX_INTERVAL: u16 = 48; // x 1.25ms
const BLE_LATENCY: u16 = 0; // Number of packets that can be missed, extending interval
const BLE_TIMEOUT: u16 = 500; // x10ms
const BUTTON_PRESSED: [u8; 1] = [0x1];
const BUTTON_RELEASED: [u8; 1] = [0x0];
const DEVICE_NAME: &str = "Gem Remotes";
const UUID_SERVICE_PAIR: BleUuid = uuid128!("9966ad5a-f13c-4b61-ba66-0861e08d09b4");
@ -31,9 +34,13 @@ pub struct BleServer {
impl BleServer {
pub fn new(dp: &mut Dispatch) -> Self {
let cmds = vec![
Commands::BluetoothUp { data: 0 },
Commands::BluetoothDown { data: 0 },
Commands::BluetoothStop { data: 0 },
// Switch to getting and updating notices; use the command version for sending commands only.
//Commands::BluetoothUp { data: 0 },
//Commands::BluetoothDown { data: 0 },
//Commands::BluetoothStop { data: 0 },
Commands::NotifyMotorDown,
Commands::NotifyMotorStop,
Commands::NotifyMotorUp,
];
let r = dp.get_callback_channel(&cmds);
let s = dp.get_cmd_channel();
@ -45,11 +52,9 @@ impl BleServer {
pub async fn run(&mut self) -> Result<()> {
match self.do_run().await {
Ok(_) => {}
Err(e) => {error!("Bluetooth task encountered error {}", e);}
Ok(_) => {error!("Exited bluetooth server wait loop with no error.");panic!();}
Err(e) => {error!("Bluetooth task encountered error {}", e);panic!();}
}
Ok(()) //TODO this is not ok; reboot the chip!
//TODO: we need a structure like this at each spawn point;; apparently functions don't pass errors up tasks.
}
pub async fn do_run(&mut self) -> Result<()> {
@ -71,7 +76,7 @@ impl BleServer {
);
button_up.lock().set_value(&[0])
.on_write(closure!(clone sender, |args: &mut OnWriteArgs| {
on_single_byte(&sender, args, Commands::BluetoothUp {data: 0})
on_bluetooth_cmd(&sender, args, Commands::BluetoothUp {data: 0})
}));
let button_down = lift_service.lock().create_characteristic(
@ -80,7 +85,7 @@ impl BleServer {
);
button_down.lock().set_value(&[0])
.on_write(closure!(clone sender, |args: &mut OnWriteArgs| {
on_single_byte(&sender, args, Commands::BluetoothDown {data: 0})
on_bluetooth_cmd(&sender, args, Commands::BluetoothDown {data: 0})
}));
let button_stop = lift_service.lock().create_characteristic(
@ -89,7 +94,7 @@ impl BleServer {
);
button_stop.lock().set_value(&[1])
.on_write(closure!(clone sender, |args: &mut OnWriteArgs| {
on_single_byte(&sender, args, Commands::BluetoothStop {data: 0})
on_bluetooth_cmd(&sender, args, Commands::BluetoothStop {data: 0})
}));
@ -99,26 +104,29 @@ impl BleServer {
advertise_pairing(ble_advertiser)?;
loop {
debug!("Waiting for updates");
debug!("Waiting for updates that should be notified via bluetooth");
let cmd = self.recv_q.recv().await?;
trace!("Received update to bluetooth variable {:?}", cmd);
match cmd {
Commands::BluetoothUp { data } => {
//TODO: this sends a notify even if the command initially came from phone. Is this correct?
trace!("Updating BluetoothUp with {:?}", data);
button_up.lock().set_value(&[data]).notify();
// TODO: This logic (if one button is pressed others are released) could be done in app instead.
Commands::NotifyMotorUp => {
button_up.lock().set_value(&BUTTON_PRESSED).notify();
button_down.lock().set_value(&BUTTON_RELEASED).notify();
button_stop.lock().set_value(&BUTTON_RELEASED).notify();
}
Commands::BluetoothDown { data } => {
trace!("Updating BluetoothDown with {:?}", data);
button_down.lock().set_value(&[data]).notify();
Commands::NotifyMotorDown => {
button_up.lock().set_value(&BUTTON_RELEASED).notify();
button_down.lock().set_value(&BUTTON_PRESSED).notify();
button_stop.lock().set_value(&BUTTON_RELEASED).notify();
}
Commands::BluetoothStop { data} => {
trace!("Updating BluetoothStop with {:?}", data);
button_stop.lock().set_value(&[data]).notify();
Commands::NotifyMotorStop => {
button_up.lock().set_value(&BUTTON_RELEASED).notify();
button_down.lock().set_value(&BUTTON_RELEASED).notify();
button_stop.lock().set_value(&BUTTON_PRESSED).notify();
}
_ => {
error!("Invalid command received by bluetooth handler {:?}", cmd);
// No need to reboot as state is recoverable.
}
}
}
@ -126,26 +134,30 @@ impl BleServer {
}
fn on_single_byte(sender: &SendQ, args: &mut OnWriteArgs, cmd: Commands) {
fn on_bluetooth_cmd(sender: &SendQ, args: &mut OnWriteArgs, cmd: Commands) {
let v = args.recv_data();
//TODO: add "update" versions of these commands, instead of the "got changes from bluetooth" versions, and handle those instead.
match cmd {
// receiving incorrect data isn't fatal, but being unable to send events is.
let attempt = match cmd {
Commands::BluetoothUp { data: _ } => {
if v.len() > 0 {
sender.send_blocking(Commands::BluetoothUp {data: v[0]} ).ok();
} else {error!("Received zero-byte bluetooth characteristic update {:?}", cmd)}
sender.send_blocking(Commands::BluetoothUp {data: v[0]} )
} else {error!("Received zero-byte bluetooth characteristic update {:?}", cmd); Ok(())}
}
Commands::BluetoothDown { data: _ } => {
if v.len() > 0 {
sender.send_blocking(Commands::BluetoothDown {data: v[0]} ).ok();
} else {error!("Received zero-byte bluetooth characteristic update {:?}", cmd)}
sender.send_blocking(Commands::BluetoothDown {data: v[0]} )
} else {error!("Received zero-byte bluetooth characteristic update {:?}", cmd); Ok(())}
}
Commands::BluetoothStop { data: _ } => {
if v.len() > 0 {
sender.send_blocking(Commands::BluetoothStop {data: v[0]} ).ok();
} else {error!("Received zero-byte bluetooth characteristic update {:?}", cmd)}
sender.send_blocking(Commands::BluetoothStop {data: v[0]} )
} else {error!("Received zero-byte bluetooth characteristic update {:?}", cmd); Ok(())}
}
_ => {error!("Tried to handle an unknown bluetooth command: {:?}",cmd);}
_ => {error!("Tried to handle an unknown bluetooth command: {:?}",cmd);Ok(())}
};
match attempt {
Ok(_) => {}
Err(_) => {panic!("Unable to send notifications of bluetooth events")}
}
}