Skip to content

Commit ebde1c1

Browse files
committed
Adding split buffer processing
process_bytes and process_buffer to handle hid-io-core where different threads often handle buffer generation and buffer processing. This is different than embedded where it's usually the same processing loop as you want to handle the buffer quickly as to release memory more quickly Also fixing the staticlib library type when using hid-io-protocol as a rust dependency
1 parent 43fd7b3 commit ebde1c1

File tree

4 files changed

+86
-12
lines changed

4 files changed

+86
-12
lines changed

hid-io-protocol/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ edition = "2018"
1818

1919
[lib]
2020
name = "hid_io_protocol"
21-
crate-type = ["staticlib"]
21+
crate-type = ["rlib", "staticlib"]
2222

2323

2424
[features]

hid-io-protocol/src/commands/mod.rs

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ mod test;
4141

4242
#[derive(Debug)]
4343
pub enum CommandError {
44+
BufferInUse,
45+
BufferNotReady,
4446
DataVecNoData,
4547
DataVecTooSmall,
4648
IdNotImplemented(HidIoCommandID),
@@ -430,6 +432,7 @@ trait Commands<
430432
fn rx_bytebuffer(&mut self) -> &mut buffer::Buffer<RX, N>;
431433
fn rx_packetbuffer(&self) -> &HidIoPacketBuffer<H>;
432434
fn rx_packetbuffer_mut(&mut self) -> &mut HidIoPacketBuffer<H>;
435+
fn rx_packetbuffer_set(&mut self, buf: HidIoPacketBuffer<H>);
433436
fn rx_packetbuffer_clear(&mut self);
434437
fn supported_id(&self, id: HidIoCommandID) -> bool;
435438

@@ -452,18 +455,15 @@ trait Commands<
452455
// Decode chunk
453456
match self.rx_packetbuffer_mut().decode_packet(&buf) {
454457
Ok(_recv) => {
455-
buffer_count += 1;
458+
// Make sure buffer is ready
459+
if self.rx_packetbuffer().done {
460+
buffer_count += 1;
456461

457-
// Handle packet type
458-
match self.rx_packetbuffer().ptype {
459-
HidIoPacketType::Sync => {
462+
// Handle sync packet type
463+
if let HidIoPacketType::Sync = self.rx_packetbuffer().ptype {
460464
debug!("Sync. Resetting buffer");
461465
self.rx_packetbuffer_clear();
462466
}
463-
HidIoPacketType::ACK => {}
464-
HidIoPacketType::NAK => {}
465-
HidIoPacketType::Continued | HidIoPacketType::Data => {}
466-
HidIoPacketType::NAData | HidIoPacketType::NAContinued => {}
467467
}
468468
}
469469
Err(e) => {
@@ -485,6 +485,74 @@ trait Commands<
485485
Ok(buffer_count)
486486
}
487487

488+
/// Generate a single HidIoPacketBuffer from the incoming byte
489+
/// stream
490+
/// Useful when byte and buffer processing are handled separately
491+
/// If the buffer is not ready yet the buffer is processed
492+
/// as much as possible and can be called again (when bytes are
493+
/// ready).
494+
fn process_bytes(&mut self) -> Result<&HidIoPacketBuffer<H>, CommandError> {
495+
loop {
496+
// Retrieve vec chunk
497+
if let Some(buf) = self.rx_bytebuffer().dequeue() {
498+
// Decode chunk
499+
match self.rx_packetbuffer_mut().decode_packet(&buf) {
500+
Ok(_recv) => {
501+
// Only handle buffer if ready
502+
if self.rx_packetbuffer().done {
503+
// Handle sync packet type
504+
match self.rx_packetbuffer().ptype {
505+
HidIoPacketType::Sync => {
506+
debug!("Sync. Resetting buffer");
507+
self.rx_packetbuffer_clear();
508+
}
509+
_ => {
510+
return Ok(self.rx_packetbuffer());
511+
}
512+
}
513+
}
514+
}
515+
Err(e) => {
516+
error!("Decode error: {:?} {:?}", e, buf);
517+
return Err(CommandError::PacketDecodeError(e));
518+
}
519+
}
520+
} else {
521+
return Err(CommandError::BufferNotReady);
522+
}
523+
}
524+
}
525+
526+
/// Process an already generate buffer
527+
/// Useful in situations where buffers are passed around instead
528+
/// of bytes buffers
529+
fn process_buffer(&mut self, buf: HidIoPacketBuffer<H>) -> Result<(), CommandError>
530+
where
531+
<Self as Commands<TX, RX, N, H, ID>>::ID32: ArrayLength<u8>,
532+
{
533+
// Make sure existing buffer is empty and unused
534+
let pbuf = self.rx_packetbuffer();
535+
if pbuf.done || pbuf.data.len() > 0 {
536+
return Err(CommandError::BufferInUse);
537+
}
538+
539+
// Incoming buffer is not ready
540+
if !buf.done {
541+
return Err(CommandError::BufferNotReady);
542+
}
543+
544+
// Set buffer
545+
self.rx_packetbuffer_set(buf);
546+
547+
// Process buffer
548+
self.rx_message_handling()?;
549+
550+
// Clear buffer
551+
self.rx_packetbuffer_clear();
552+
553+
Ok(())
554+
}
555+
488556
/// Simple empty ack
489557
fn empty_ack(&mut self) -> Result<(), CommandError> {
490558
// Build empty ACK

hid-io-protocol/src/commands/test.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ where
128128
fn rx_packetbuffer_mut(&mut self) -> &mut HidIoPacketBuffer<H> {
129129
&mut self.rx_packetbuf
130130
}
131+
fn rx_packetbuffer_set(&mut self, buf: HidIoPacketBuffer<H>) {
132+
self.rx_packetbuf = HidIoPacketBuffer {
133+
ptype: buf.ptype,
134+
id: buf.id,
135+
max_len: buf.max_len,
136+
data: buf.data,
137+
done: buf.done,
138+
};
139+
}
131140
fn rx_packetbuffer_clear(&mut self) {
132141
self.rx_packetbuf = HidIoPacketBuffer::new();
133142
}

src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ pub mod module;
4444
/// parsing for different data types
4545
pub mod protocol;
4646

47-
//pub mod hid_io_protocol;
48-
//use hid_io_protocol;
49-
5047
/// Compile time information
5148
pub mod built_info {
5249
// This file is generated at build time using build.rs

0 commit comments

Comments
 (0)