Skip to content

Commit

Permalink
Detect bad host states
Browse files Browse the repository at this point in the history
Generate a Core Device Status Ntf with state error when
commands are received before the Core Device Reset command
  • Loading branch information
hchataing authored and SilverBzH committed Jun 17, 2024
1 parent dbcb4e9 commit 4ac90d1
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
27 changes: 22 additions & 5 deletions src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ impl Default for DeviceConfig {
}

pub struct Device {
/// Flag set when the device has received the Core Device Reset command.
/// The first command received by the device is expected to be Core Device
/// Reset, receiving any other command before this is indicative of a
/// bad host state.
is_reset: bool,
pub handle: usize,
pub mac_address: MacAddress,
config: DeviceConfig,
Expand All @@ -108,7 +113,6 @@ pub struct Device {
pub tx: mpsc::UnboundedSender<UciPacket>,
pica_tx: mpsc::Sender<PicaCommand>,
country_code: [u8; 2],

pub n_active_sessions: usize,
}

Expand All @@ -122,6 +126,7 @@ impl Device {
Device {
handle,
mac_address,
is_reset: false,
config: Default::default(),
state: DeviceState::DeviceStateError, // Will be overwitten
sessions: Default::default(),
Expand Down Expand Up @@ -216,18 +221,19 @@ impl Device {
log::debug!("[{}] DeviceReset", self.handle);
log::debug!(" reset_config={:?}", reset_config);

let status = match reset_config {
ResetConfig::UwbsReset => uci::Status::Ok,
};
*self = Device::new(
self.handle,
self.mac_address,
self.tx.clone(),
self.pica_tx.clone(),
);
self.is_reset = true;
self.init();

CoreDeviceResetRspBuilder { status }.build()
CoreDeviceResetRspBuilder {
status: uci::Status::Ok,
}
.build()
}

fn core_get_device_info(&self, _cmd: CoreGetDeviceInfoCmd) -> CoreGetDeviceInfoRsp {
Expand Down Expand Up @@ -969,6 +975,17 @@ impl Device {
use SessionConfigPacketChild::*;
use SessionControlPacketChild::*;

// Check whether the first command received is the Core Device
// Reset command. The controller responds with Device Status
// Notification with DEVICE_STATE_ERROR otherwise.
if !self.is_reset && !cmd.is_core_device_reset_cmd() {
return CoreDeviceStatusNtfBuilder {
device_state: DeviceState::DeviceStateError,
}
.build()
.into();
}

match cmd.specialize() {
CorePacket(cmd) => match cmd.specialize() {
CoreDeviceResetCmd(cmd) => self.core_device_reset(cmd).into(),
Expand Down
12 changes: 12 additions & 0 deletions src/packets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ pub mod uci {

include!(concat!(env!("OUT_DIR"), "/uci_packets.rs"));

impl ControlPacket {
pub fn is_core_device_reset_cmd(&self) -> bool {
matches!(
self.controlpacket.child,
ControlPacketDataChild::CorePacket(CorePacketData {
child: CorePacketDataChild::CoreDeviceResetCmd(_),
..
})
)
}
}

/// Size of common UCI packet header.
pub const COMMON_HEADER_SIZE: usize = 1;
/// Size of UCI packet headers.
Expand Down

0 comments on commit 4ac90d1

Please sign in to comment.