Compare commits

...

3 commits

14 changed files with 160 additions and 481 deletions

View file

@ -1,7 +1,7 @@
use std::env; use std::env;
use std::path::Path; use std::path::Path;
use micropb_gen::{Config, Generator}; use micropb_gen::Generator;
fn proto_generate() { fn proto_generate() {
let firmware_dir = Path::new(env!("CARGO_MANIFEST_DIR")); let firmware_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
@ -14,15 +14,9 @@ fn proto_generate() {
let mut g = Generator::new(); let mut g = Generator::new();
g.use_container_heapless() g.use_container_heapless()
.configure(".test.TestResponse.f2", Config::new().max_bytes(16))
.configure(".test.TestResponse.f4", Config::new().max_bytes(8))
.add_protoc_arg(format!("-I{}", proto_dir.display())) .add_protoc_arg(format!("-I{}", proto_dir.display()))
.compile_protos( .compile_protos(
&[ &[proto_dir.join("api.proto"), proto_dir.join("echo.proto")],
proto_dir.join("api.proto"),
proto_dir.join("echo.proto"),
proto_dir.join("test.proto"),
],
target_dir.join("proto.rs"), target_dir.join("proto.rs"),
) )
.unwrap(); .unwrap();

View file

@ -4,7 +4,7 @@ use never;
use thiserror::Error; use thiserror::Error;
use super::framed; use super::framed;
use crate::{crc, proto}; use crate::{crc, println, proto};
pub const SYNC_BYTE: u8 = 0xfc; pub const SYNC_BYTE: u8 = 0xfc;
pub const MESSAGE_LENGTH_SIZE: usize = 2; pub const MESSAGE_LENGTH_SIZE: usize = 2;
@ -39,8 +39,10 @@ pub async fn send_target_message<T>(
where where
T: framed::Sender, T: framed::Sender,
{ {
println!("sending sync");
ftx.send_sync()?; ftx.send_sync()?;
println!("message is {=u16} bytes", msg.compute_size() as u16);
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_possible_truncation)]
let encoded_size = (msg.compute_size() as u16).to_le_bytes(); let encoded_size = (msg.compute_size() as u16).to_le_bytes();
ftx.send_frame_fragment(&encoded_size)?; ftx.send_frame_fragment(&encoded_size)?;
@ -54,6 +56,7 @@ where
msg.encode(&mut encoder)?; msg.encode(&mut encoder)?;
let crc_result = crc_stream.result().to_le_bytes(); let crc_result = crc_stream.result().to_le_bytes();
println!("sending CRC");
ftx.send_frame_fragment(&crc_result) ftx.send_frame_fragment(&crc_result)
} }
@ -81,11 +84,15 @@ where
{ {
frx.receive_sync().await.or(Err(ReceiveError::Sync))?; frx.receive_sync().await.or(Err(ReceiveError::Sync))?;
println!("got sync");
// sync byte was seen, read the length of the message // sync byte was seen, read the length of the message
frx.receive_frame_fragment(0, MESSAGE_LENGTH_SIZE) frx.receive_frame_fragment(0, MESSAGE_LENGTH_SIZE)
.await .await
.map_err(ReceiveError::Framing)?; .map_err(ReceiveError::Framing)?;
println!("got length");
// get the message length from the buffer // get the message length from the buffer
let message_len = LittleEndian::read_u16(&frx.buf()[..MESSAGE_LENGTH_SIZE]) as usize; let message_len = LittleEndian::read_u16(&frx.buf()[..MESSAGE_LENGTH_SIZE]) as usize;
@ -95,12 +102,16 @@ where
.await .await
.map_err(ReceiveError::Framing)?; .map_err(ReceiveError::Framing)?;
println!("got message");
// read the CRC-16 of the message // read the CRC-16 of the message
let crc_pos = message_pos + message_len; let crc_pos = message_pos + message_len;
frx.receive_frame_fragment(crc_pos, MESSAGE_CRC_SIZE) frx.receive_frame_fragment(crc_pos, MESSAGE_CRC_SIZE)
.await .await
.map_err(ReceiveError::Framing)?; .map_err(ReceiveError::Framing)?;
println!("got CRC");
// get the expected CRC-16 from the buffer // get the expected CRC-16 from the buffer
let expected_crc = LittleEndian::read_u16(&frx.buf()[crc_pos..crc_pos + MESSAGE_CRC_SIZE]); let expected_crc = LittleEndian::read_u16(&frx.buf()[crc_pos..crc_pos + MESSAGE_CRC_SIZE]);
// compute the actual CRC-16 // compute the actual CRC-16
@ -112,6 +123,8 @@ where
return Err(ReceiveError::Crc); return Err(ReceiveError::Crc);
} }
println!("CRC valid");
// at this point the buffer has been confirmed to contain a // at this point the buffer has been confirmed to contain a
// valid message frame, so any failures beyond this point can // valid message frame, so any failures beyond this point can
// only drop the message, it cannot be re-parsed // only drop the message, it cannot be re-parsed
@ -124,5 +137,9 @@ where
frx.remove_frame(crc_pos + MESSAGE_CRC_SIZE); frx.remove_frame(crc_pos + MESSAGE_CRC_SIZE);
if result.is_err() {
println!("decode error");
}
result result
} }

View file

@ -1,46 +1,18 @@
pub mod echo_ { pub mod echo_ {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct EchoRequest { pub struct EchoRequest {}
pub r#data: u32,
}
impl ::core::default::Default for EchoRequest { impl ::core::default::Default for EchoRequest {
fn default() -> Self { fn default() -> Self {
Self { Self {}
r#data: ::core::default::Default::default(),
}
} }
} }
impl ::core::cmp::PartialEq for EchoRequest { impl ::core::cmp::PartialEq for EchoRequest {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
let mut ret = true; let mut ret = true;
ret &= (self.r#data == other.r#data);
ret ret
} }
} }
impl EchoRequest { impl EchoRequest {}
///Return a reference to `data`
#[inline]
pub fn r#data(&self) -> &u32 {
&self.r#data
}
///Return a mutable reference to `data`
#[inline]
pub fn mut_data(&mut self) -> &mut u32 {
&mut self.r#data
}
///Set the value of `data`
#[inline]
pub fn set_data(&mut self, value: u32) -> &mut Self {
self.r#data = value.into();
self
}
///Builder method that sets the value of `data`. Useful for initializing the message.
#[inline]
pub fn init_data(mut self, value: u32) -> Self {
self.r#data = value.into();
self
}
}
impl ::micropb::MessageDecode for EchoRequest { impl ::micropb::MessageDecode for EchoRequest {
fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>(
&mut self, &mut self,
@ -53,16 +25,6 @@ pub mod echo_ {
let tag = decoder.decode_tag()?; let tag = decoder.decode_tag()?;
match tag.field_num() { match tag.field_num() {
0 => return Err(::micropb::DecodeError::ZeroField), 0 => return Err(::micropb::DecodeError::ZeroField),
1u32 => {
let mut_ref = &mut self.r#data;
{
let val = decoder.decode_varint32()?;
let val_ref = &val;
if *val_ref != 0 {
*mut_ref = val as _;
}
};
}
_ => { _ => {
decoder.skip_wire_value(tag.wire_type())?; decoder.skip_wire_value(tag.wire_type())?;
} }
@ -77,69 +39,28 @@ pub mod echo_ {
encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>,
) -> Result<(), IMPL_MICROPB_WRITE::Error> { ) -> Result<(), IMPL_MICROPB_WRITE::Error> {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode}; use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
{
let val_ref = &self.r#data;
if *val_ref != 0 {
encoder.encode_varint32(8u32)?;
encoder.encode_varint32(*val_ref as _)?;
}
}
Ok(()) Ok(())
} }
fn compute_size(&self) -> usize { fn compute_size(&self) -> usize {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode}; use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
let mut size = 0; let mut size = 0;
{
let val_ref = &self.r#data;
if *val_ref != 0 {
size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _);
}
}
size size
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct EchoResponse { pub struct EchoResponse {}
pub r#data: u32,
}
impl ::core::default::Default for EchoResponse { impl ::core::default::Default for EchoResponse {
fn default() -> Self { fn default() -> Self {
Self { Self {}
r#data: ::core::default::Default::default(),
}
} }
} }
impl ::core::cmp::PartialEq for EchoResponse { impl ::core::cmp::PartialEq for EchoResponse {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
let mut ret = true; let mut ret = true;
ret &= (self.r#data == other.r#data);
ret ret
} }
} }
impl EchoResponse { impl EchoResponse {}
///Return a reference to `data`
#[inline]
pub fn r#data(&self) -> &u32 {
&self.r#data
}
///Return a mutable reference to `data`
#[inline]
pub fn mut_data(&mut self) -> &mut u32 {
&mut self.r#data
}
///Set the value of `data`
#[inline]
pub fn set_data(&mut self, value: u32) -> &mut Self {
self.r#data = value.into();
self
}
///Builder method that sets the value of `data`. Useful for initializing the message.
#[inline]
pub fn init_data(mut self, value: u32) -> Self {
self.r#data = value.into();
self
}
}
impl ::micropb::MessageDecode for EchoResponse { impl ::micropb::MessageDecode for EchoResponse {
fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>(
&mut self, &mut self,
@ -152,16 +73,6 @@ pub mod echo_ {
let tag = decoder.decode_tag()?; let tag = decoder.decode_tag()?;
match tag.field_num() { match tag.field_num() {
0 => return Err(::micropb::DecodeError::ZeroField), 0 => return Err(::micropb::DecodeError::ZeroField),
1u32 => {
let mut_ref = &mut self.r#data;
{
let val = decoder.decode_varint32()?;
let val_ref = &val;
if *val_ref != 0 {
*mut_ref = val as _;
}
};
}
_ => { _ => {
decoder.skip_wire_value(tag.wire_type())?; decoder.skip_wire_value(tag.wire_type())?;
} }
@ -176,263 +87,11 @@ pub mod echo_ {
encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>,
) -> Result<(), IMPL_MICROPB_WRITE::Error> { ) -> Result<(), IMPL_MICROPB_WRITE::Error> {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode}; use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
{
let val_ref = &self.r#data;
if *val_ref != 0 {
encoder.encode_varint32(8u32)?;
encoder.encode_varint32(*val_ref as _)?;
}
}
Ok(()) Ok(())
} }
fn compute_size(&self) -> usize { fn compute_size(&self) -> usize {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode}; use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
let mut size = 0; let mut size = 0;
{
let val_ref = &self.r#data;
if *val_ref != 0 {
size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _);
}
}
size
}
}
}
pub mod test_ {
#[derive(Debug, Clone)]
pub struct TestResponse {
pub r#f1: u32,
pub r#f2: ::micropb::heapless::String<16>,
pub r#f3: bool,
pub r#f4: ::micropb::heapless::Vec<u8, 8>,
}
impl ::core::default::Default for TestResponse {
fn default() -> Self {
Self {
r#f1: ::core::default::Default::default(),
r#f2: ::core::default::Default::default(),
r#f3: ::core::default::Default::default(),
r#f4: ::core::default::Default::default(),
}
}
}
impl ::core::cmp::PartialEq for TestResponse {
fn eq(&self, other: &Self) -> bool {
let mut ret = true;
ret &= (self.r#f1 == other.r#f1);
ret &= (self.r#f2 == other.r#f2);
ret &= (self.r#f3 == other.r#f3);
ret &= (self.r#f4 == other.r#f4);
ret
}
}
impl TestResponse {
///Return a reference to `f1`
#[inline]
pub fn r#f1(&self) -> &u32 {
&self.r#f1
}
///Return a mutable reference to `f1`
#[inline]
pub fn mut_f1(&mut self) -> &mut u32 {
&mut self.r#f1
}
///Set the value of `f1`
#[inline]
pub fn set_f1(&mut self, value: u32) -> &mut Self {
self.r#f1 = value.into();
self
}
///Builder method that sets the value of `f1`. Useful for initializing the message.
#[inline]
pub fn init_f1(mut self, value: u32) -> Self {
self.r#f1 = value.into();
self
}
///Return a reference to `f2`
#[inline]
pub fn r#f2(&self) -> &::micropb::heapless::String<16> {
&self.r#f2
}
///Return a mutable reference to `f2`
#[inline]
pub fn mut_f2(&mut self) -> &mut ::micropb::heapless::String<16> {
&mut self.r#f2
}
///Set the value of `f2`
#[inline]
pub fn set_f2(&mut self, value: ::micropb::heapless::String<16>) -> &mut Self {
self.r#f2 = value.into();
self
}
///Builder method that sets the value of `f2`. Useful for initializing the message.
#[inline]
pub fn init_f2(mut self, value: ::micropb::heapless::String<16>) -> Self {
self.r#f2 = value.into();
self
}
///Return a reference to `f3`
#[inline]
pub fn r#f3(&self) -> &bool {
&self.r#f3
}
///Return a mutable reference to `f3`
#[inline]
pub fn mut_f3(&mut self) -> &mut bool {
&mut self.r#f3
}
///Set the value of `f3`
#[inline]
pub fn set_f3(&mut self, value: bool) -> &mut Self {
self.r#f3 = value.into();
self
}
///Builder method that sets the value of `f3`. Useful for initializing the message.
#[inline]
pub fn init_f3(mut self, value: bool) -> Self {
self.r#f3 = value.into();
self
}
///Return a reference to `f4`
#[inline]
pub fn r#f4(&self) -> &::micropb::heapless::Vec<u8, 8> {
&self.r#f4
}
///Return a mutable reference to `f4`
#[inline]
pub fn mut_f4(&mut self) -> &mut ::micropb::heapless::Vec<u8, 8> {
&mut self.r#f4
}
///Set the value of `f4`
#[inline]
pub fn set_f4(&mut self, value: ::micropb::heapless::Vec<u8, 8>) -> &mut Self {
self.r#f4 = value.into();
self
}
///Builder method that sets the value of `f4`. Useful for initializing the message.
#[inline]
pub fn init_f4(mut self, value: ::micropb::heapless::Vec<u8, 8>) -> Self {
self.r#f4 = value.into();
self
}
}
impl ::micropb::MessageDecode for TestResponse {
fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>(
&mut self,
decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>,
len: usize,
) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> {
use ::micropb::{PbVec, PbMap, PbString, FieldDecode};
let before = decoder.bytes_read();
while decoder.bytes_read() - before < len {
let tag = decoder.decode_tag()?;
match tag.field_num() {
0 => return Err(::micropb::DecodeError::ZeroField),
1u32 => {
let mut_ref = &mut self.r#f1;
{
let val = decoder.decode_varint32()?;
let val_ref = &val;
if *val_ref != 0 {
*mut_ref = val as _;
}
};
}
2u32 => {
let mut_ref = &mut self.r#f2;
{
decoder
.decode_string(mut_ref, ::micropb::Presence::Implicit)?;
};
}
3u32 => {
let mut_ref = &mut self.r#f3;
{
let val = decoder.decode_bool()?;
let val_ref = &val;
if *val_ref {
*mut_ref = val as _;
}
};
}
4u32 => {
let mut_ref = &mut self.r#f4;
{
decoder
.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?;
};
}
_ => {
decoder.skip_wire_value(tag.wire_type())?;
}
}
}
Ok(())
}
}
impl ::micropb::MessageEncode for TestResponse {
fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>(
&self,
encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>,
) -> Result<(), IMPL_MICROPB_WRITE::Error> {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
{
let val_ref = &self.r#f1;
if *val_ref != 0 {
encoder.encode_varint32(8u32)?;
encoder.encode_varint32(*val_ref as _)?;
}
}
{
let val_ref = &self.r#f2;
if !val_ref.is_empty() {
encoder.encode_varint32(18u32)?;
encoder.encode_string(val_ref)?;
}
}
{
let val_ref = &self.r#f3;
if *val_ref {
encoder.encode_varint32(24u32)?;
encoder.encode_bool(*val_ref)?;
}
}
{
let val_ref = &self.r#f4;
if !val_ref.is_empty() {
encoder.encode_varint32(34u32)?;
encoder.encode_bytes(val_ref)?;
}
}
Ok(())
}
fn compute_size(&self) -> usize {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
let mut size = 0;
{
let val_ref = &self.r#f1;
if *val_ref != 0 {
size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _);
}
}
{
let val_ref = &self.r#f2;
if !val_ref.is_empty() {
size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len());
}
}
{
let val_ref = &self.r#f3;
if *val_ref {
size += 1usize + 1;
}
}
{
let val_ref = &self.r#f4;
if !val_ref.is_empty() {
size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len());
}
}
size size
} }
} }
@ -446,11 +105,13 @@ pub mod api_ {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct HostMessage { pub struct HostMessage {
pub r#id: u32,
pub r#msg: ::core::option::Option<HostMessage_::Msg>, pub r#msg: ::core::option::Option<HostMessage_::Msg>,
} }
impl ::core::default::Default for HostMessage { impl ::core::default::Default for HostMessage {
fn default() -> Self { fn default() -> Self {
Self { Self {
r#id: ::core::default::Default::default(),
r#msg: ::core::default::Default::default(), r#msg: ::core::default::Default::default(),
} }
} }
@ -458,11 +119,35 @@ pub mod api_ {
impl ::core::cmp::PartialEq for HostMessage { impl ::core::cmp::PartialEq for HostMessage {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
let mut ret = true; let mut ret = true;
ret &= (self.r#id == other.r#id);
ret &= (self.r#msg == other.r#msg); ret &= (self.r#msg == other.r#msg);
ret ret
} }
} }
impl HostMessage {} impl HostMessage {
///Return a reference to `id`
#[inline]
pub fn r#id(&self) -> &u32 {
&self.r#id
}
///Return a mutable reference to `id`
#[inline]
pub fn mut_id(&mut self) -> &mut u32 {
&mut self.r#id
}
///Set the value of `id`
#[inline]
pub fn set_id(&mut self, value: u32) -> &mut Self {
self.r#id = value.into();
self
}
///Builder method that sets the value of `id`. Useful for initializing the message.
#[inline]
pub fn init_id(mut self, value: u32) -> Self {
self.r#id = value.into();
self
}
}
impl ::micropb::MessageDecode for HostMessage { impl ::micropb::MessageDecode for HostMessage {
fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>(
&mut self, &mut self,
@ -476,6 +161,16 @@ pub mod api_ {
match tag.field_num() { match tag.field_num() {
0 => return Err(::micropb::DecodeError::ZeroField), 0 => return Err(::micropb::DecodeError::ZeroField),
1u32 => { 1u32 => {
let mut_ref = &mut self.r#id;
{
let val = decoder.decode_varint32()?;
let val_ref = &val;
if *val_ref != 0 {
*mut_ref = val as _;
}
};
}
2u32 => {
let mut_ref = loop { let mut_ref = loop {
if let ::core::option::Option::Some(variant) = &mut self if let ::core::option::Option::Some(variant) = &mut self
.r#msg .r#msg
@ -504,11 +199,18 @@ pub mod api_ {
encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>,
) -> Result<(), IMPL_MICROPB_WRITE::Error> { ) -> Result<(), IMPL_MICROPB_WRITE::Error> {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode}; use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
{
let val_ref = &self.r#id;
if *val_ref != 0 {
encoder.encode_varint32(8u32)?;
encoder.encode_varint32(*val_ref as _)?;
}
}
if let Some(oneof) = &self.r#msg { if let Some(oneof) = &self.r#msg {
match &*oneof { match &*oneof {
HostMessage_::Msg::Echo(val_ref) => { HostMessage_::Msg::Echo(val_ref) => {
let val_ref = &*val_ref; let val_ref = &*val_ref;
encoder.encode_varint32(10u32)?; encoder.encode_varint32(18u32)?;
val_ref.encode_len_delimited(encoder)?; val_ref.encode_len_delimited(encoder)?;
} }
} }
@ -518,6 +220,12 @@ pub mod api_ {
fn compute_size(&self) -> usize { fn compute_size(&self) -> usize {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode}; use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
let mut size = 0; let mut size = 0;
{
let val_ref = &self.r#id;
if *val_ref != 0 {
size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _);
}
}
if let Some(oneof) = &self.r#msg { if let Some(oneof) = &self.r#msg {
match &*oneof { match &*oneof {
HostMessage_::Msg::Echo(val_ref) => { HostMessage_::Msg::Echo(val_ref) => {
@ -537,16 +245,17 @@ pub mod api_ {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum Msg { pub enum Msg {
Echo(super::super::echo_::EchoResponse), Echo(super::super::echo_::EchoResponse),
Test(super::super::test_::TestResponse),
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct TargetMessage { pub struct TargetMessage {
pub r#id: u32,
pub r#msg: ::core::option::Option<TargetMessage_::Msg>, pub r#msg: ::core::option::Option<TargetMessage_::Msg>,
} }
impl ::core::default::Default for TargetMessage { impl ::core::default::Default for TargetMessage {
fn default() -> Self { fn default() -> Self {
Self { Self {
r#id: ::core::default::Default::default(),
r#msg: ::core::default::Default::default(), r#msg: ::core::default::Default::default(),
} }
} }
@ -554,11 +263,35 @@ pub mod api_ {
impl ::core::cmp::PartialEq for TargetMessage { impl ::core::cmp::PartialEq for TargetMessage {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
let mut ret = true; let mut ret = true;
ret &= (self.r#id == other.r#id);
ret &= (self.r#msg == other.r#msg); ret &= (self.r#msg == other.r#msg);
ret ret
} }
} }
impl TargetMessage {} impl TargetMessage {
///Return a reference to `id`
#[inline]
pub fn r#id(&self) -> &u32 {
&self.r#id
}
///Return a mutable reference to `id`
#[inline]
pub fn mut_id(&mut self) -> &mut u32 {
&mut self.r#id
}
///Set the value of `id`
#[inline]
pub fn set_id(&mut self, value: u32) -> &mut Self {
self.r#id = value.into();
self
}
///Builder method that sets the value of `id`. Useful for initializing the message.
#[inline]
pub fn init_id(mut self, value: u32) -> Self {
self.r#id = value.into();
self
}
}
impl ::micropb::MessageDecode for TargetMessage { impl ::micropb::MessageDecode for TargetMessage {
fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>(
&mut self, &mut self,
@ -572,6 +305,16 @@ pub mod api_ {
match tag.field_num() { match tag.field_num() {
0 => return Err(::micropb::DecodeError::ZeroField), 0 => return Err(::micropb::DecodeError::ZeroField),
1u32 => { 1u32 => {
let mut_ref = &mut self.r#id;
{
let val = decoder.decode_varint32()?;
let val_ref = &val;
if *val_ref != 0 {
*mut_ref = val as _;
}
};
}
2u32 => {
let mut_ref = loop { let mut_ref = loop {
if let ::core::option::Option::Some(variant) = &mut self if let ::core::option::Option::Some(variant) = &mut self
.r#msg .r#msg
@ -588,23 +331,6 @@ pub mod api_ {
}; };
mut_ref.decode_len_delimited(decoder)?; mut_ref.decode_len_delimited(decoder)?;
} }
2u32 => {
let mut_ref = loop {
if let ::core::option::Option::Some(variant) = &mut self
.r#msg
{
if let TargetMessage_::Msg::Test(variant) = &mut *variant {
break &mut *variant;
}
}
self.r#msg = ::core::option::Option::Some(
TargetMessage_::Msg::Test(
::core::default::Default::default(),
),
);
};
mut_ref.decode_len_delimited(decoder)?;
}
_ => { _ => {
decoder.skip_wire_value(tag.wire_type())?; decoder.skip_wire_value(tag.wire_type())?;
} }
@ -619,14 +345,16 @@ pub mod api_ {
encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>,
) -> Result<(), IMPL_MICROPB_WRITE::Error> { ) -> Result<(), IMPL_MICROPB_WRITE::Error> {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode}; use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
{
let val_ref = &self.r#id;
if *val_ref != 0 {
encoder.encode_varint32(8u32)?;
encoder.encode_varint32(*val_ref as _)?;
}
}
if let Some(oneof) = &self.r#msg { if let Some(oneof) = &self.r#msg {
match &*oneof { match &*oneof {
TargetMessage_::Msg::Echo(val_ref) => { TargetMessage_::Msg::Echo(val_ref) => {
let val_ref = &*val_ref;
encoder.encode_varint32(10u32)?;
val_ref.encode_len_delimited(encoder)?;
}
TargetMessage_::Msg::Test(val_ref) => {
let val_ref = &*val_ref; let val_ref = &*val_ref;
encoder.encode_varint32(18u32)?; encoder.encode_varint32(18u32)?;
val_ref.encode_len_delimited(encoder)?; val_ref.encode_len_delimited(encoder)?;
@ -638,6 +366,12 @@ pub mod api_ {
fn compute_size(&self) -> usize { fn compute_size(&self) -> usize {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode}; use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
let mut size = 0; let mut size = 0;
{
let val_ref = &self.r#id;
if *val_ref != 0 {
size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _);
}
}
if let Some(oneof) = &self.r#msg { if let Some(oneof) = &self.r#msg {
match &*oneof { match &*oneof {
TargetMessage_::Msg::Echo(val_ref) => { TargetMessage_::Msg::Echo(val_ref) => {
@ -648,14 +382,6 @@ pub mod api_ {
val_ref.compute_size(), val_ref.compute_size(),
); );
} }
TargetMessage_::Msg::Test(val_ref) => {
let val_ref = &*val_ref;
size
+= 1usize
+ ::micropb::size::sizeof_len_record(
val_ref.compute_size(),
);
}
} }
} }
size size

View file

@ -120,9 +120,15 @@ async fn rx_task(rx: Rx) {
loop { loop {
match io::proto::receive_host_message(&mut frx, rx.crc).await { match io::proto::receive_host_message(&mut frx, rx.crc).await {
Ok(msg) => { Ok(msg) => {
println!("got host message");
handle_host_message(msg, rx.channel).await; handle_host_message(msg, rx.channel).await;
} }
Err(io::proto::ReceiveError::Sync | io::proto::ReceiveError::Crc) => {} Err(io::proto::ReceiveError::Sync) => {
println!("sync error");
}
Err(io::proto::ReceiveError::Crc) => {
println!("CRC error");
}
Err(io::proto::ReceiveError::Framing(e)) => { Err(io::proto::ReceiveError::Framing(e)) => {
match e { match e {
io::framed::AsyncReadReceiverError::BufferCapacity => { io::framed::AsyncReadReceiverError::BufferCapacity => {
@ -136,6 +142,7 @@ async fn rx_task(rx: Rx) {
// restart loop, since the sync byte seen wasn't // restart loop, since the sync byte seen wasn't
// the beginning of a message, or the sender // the beginning of a message, or the sender
// stopped sending // stopped sending
println!("timeout");
} }
#[allow(clippy::match_same_arms)] #[allow(clippy::match_same_arms)]
io::framed::AsyncReadReceiverError::Other(_) => { io::framed::AsyncReadReceiverError::Other(_) => {
@ -179,10 +186,12 @@ async fn rx_task(rx: Rx) {
async fn handle_host_message(host: HostMessage, generator: crate::TargetMessageGenerator) { async fn handle_host_message(host: HostMessage, generator: crate::TargetMessageGenerator) {
match host.msg { match host.msg {
None => {} None => {}
Some(HostMessage_::Msg::Echo(echo)) => { Some(HostMessage_::Msg::Echo(_)) => {
println!("got host echo");
generator generator
.send(TargetMessage { .send(TargetMessage {
msg: Some(TargetMessage_::Msg::Echo(EchoResponse { data: echo.data })), id: host.id,
msg: Some(TargetMessage_::Msg::Echo(EchoResponse {})),
}) })
.await; .await;
} }

View file

@ -3,17 +3,17 @@ syntax = "proto3";
package api; package api;
import "echo.proto"; import "echo.proto";
import "test.proto";
message HostMessage { message HostMessage {
uint32 id = 1;
oneof msg { oneof msg {
echo.EchoRequest echo = 1; echo.EchoRequest echo = 2;
} }
} }
message TargetMessage { message TargetMessage {
uint32 id = 1;
oneof msg { oneof msg {
echo.EchoResponse echo = 1; echo.EchoResponse echo = 2;
test.TestResponse test = 2;
} }
} }

View file

@ -3,9 +3,7 @@ syntax = "proto3";
package echo; package echo;
message EchoRequest { message EchoRequest {
uint32 data = 1;
} }
message EchoResponse { message EchoResponse {
uint32 data = 1;
} }

View file

@ -1,10 +0,0 @@
syntax = "proto3";
package test;
message TestResponse {
uint32 f1 = 1;
string f2 = 2;
bool f3 = 3;
bytes f4 = 4;
}

View file

@ -12,18 +12,17 @@ _sym_db = _symbol_database.Default()
import echo_pb2 as echo__pb2 import echo_pb2 as echo__pb2
import test_pb2 as test__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\tapi.proto\x12\x03\x61pi\x1a\necho.proto\x1a\ntest.proto\"7\n\x0bHostMessage\x12!\n\x04\x65\x63ho\x18\x01 \x01(\x0b\x32\x11.echo.EchoRequestH\x00\x42\x05\n\x03msg\"^\n\rTargetMessage\x12\"\n\x04\x65\x63ho\x18\x01 \x01(\x0b\x32\x12.echo.EchoResponseH\x00\x12\"\n\x04test\x18\x02 \x01(\x0b\x32\x12.test.TestResponseH\x00\x42\x05\n\x03msgb\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\tapi.proto\x12\x03\x61pi\x1a\necho.proto\"C\n\x0bHostMessage\x12\n\n\x02id\x18\x01 \x01(\r\x12!\n\x04\x65\x63ho\x18\x02 \x01(\x0b\x32\x11.echo.EchoRequestH\x00\x42\x05\n\x03msg\"F\n\rTargetMessage\x12\n\n\x02id\x18\x01 \x01(\r\x12\"\n\x04\x65\x63ho\x18\x02 \x01(\x0b\x32\x12.echo.EchoResponseH\x00\x42\x05\n\x03msgb\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'api_pb2', globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'api_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
_HOSTMESSAGE._serialized_start=42 _HOSTMESSAGE._serialized_start=30
_HOSTMESSAGE._serialized_end=97 _HOSTMESSAGE._serialized_end=97
_TARGETMESSAGE._serialized_start=99 _TARGETMESSAGE._serialized_start=99
_TARGETMESSAGE._serialized_end=193 _TARGETMESSAGE._serialized_end=169
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View file

@ -1,5 +1,4 @@
import echo_pb2 as _echo_pb2 import echo_pb2 as _echo_pb2
import test_pb2 as _test_pb2
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
@ -7,15 +6,17 @@ from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Opti
DESCRIPTOR: _descriptor.FileDescriptor DESCRIPTOR: _descriptor.FileDescriptor
class HostMessage(_message.Message): class HostMessage(_message.Message):
__slots__ = ["echo"] __slots__ = ["echo", "id"]
ECHO_FIELD_NUMBER: _ClassVar[int] ECHO_FIELD_NUMBER: _ClassVar[int]
ID_FIELD_NUMBER: _ClassVar[int]
echo: _echo_pb2.EchoRequest echo: _echo_pb2.EchoRequest
def __init__(self, echo: _Optional[_Union[_echo_pb2.EchoRequest, _Mapping]] = ...) -> None: ... id: int
def __init__(self, id: _Optional[int] = ..., echo: _Optional[_Union[_echo_pb2.EchoRequest, _Mapping]] = ...) -> None: ...
class TargetMessage(_message.Message): class TargetMessage(_message.Message):
__slots__ = ["echo", "test"] __slots__ = ["echo", "id"]
ECHO_FIELD_NUMBER: _ClassVar[int] ECHO_FIELD_NUMBER: _ClassVar[int]
TEST_FIELD_NUMBER: _ClassVar[int] ID_FIELD_NUMBER: _ClassVar[int]
echo: _echo_pb2.EchoResponse echo: _echo_pb2.EchoResponse
test: _test_pb2.TestResponse id: int
def __init__(self, echo: _Optional[_Union[_echo_pb2.EchoResponse, _Mapping]] = ..., test: _Optional[_Union[_test_pb2.TestResponse, _Mapping]] = ...) -> None: ... def __init__(self, id: _Optional[int] = ..., echo: _Optional[_Union[_echo_pb2.EchoResponse, _Mapping]] = ...) -> None: ...

View file

@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\necho.proto\x12\x04\x65\x63ho\"\x1b\n\x0b\x45\x63hoRequest\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\r\"\x1c\n\x0c\x45\x63hoResponse\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\rb\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\necho.proto\x12\x04\x65\x63ho\"\r\n\x0b\x45\x63hoRequest\"\x0e\n\x0c\x45\x63hoResponseb\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'echo_pb2', globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'echo_pb2', globals())
@ -21,7 +21,7 @@ if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
_ECHOREQUEST._serialized_start=20 _ECHOREQUEST._serialized_start=20
_ECHOREQUEST._serialized_end=47 _ECHOREQUEST._serialized_end=33
_ECHORESPONSE._serialized_start=49 _ECHORESPONSE._serialized_start=35
_ECHORESPONSE._serialized_end=77 _ECHORESPONSE._serialized_end=49
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View file

@ -1,17 +1,13 @@
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Optional as _Optional from typing import ClassVar as _ClassVar
DESCRIPTOR: _descriptor.FileDescriptor DESCRIPTOR: _descriptor.FileDescriptor
class EchoRequest(_message.Message): class EchoRequest(_message.Message):
__slots__ = ["data"] __slots__ = []
DATA_FIELD_NUMBER: _ClassVar[int] def __init__(self) -> None: ...
data: int
def __init__(self, data: _Optional[int] = ...) -> None: ...
class EchoResponse(_message.Message): class EchoResponse(_message.Message):
__slots__ = ["data"] __slots__ = []
DATA_FIELD_NUMBER: _ClassVar[int] def __init__(self) -> None: ...
data: int
def __init__(self, data: _Optional[int] = ...) -> None: ...

View file

@ -229,7 +229,7 @@ async def message_handler() -> None:
async def handle_target_message(tgt: TargetMessage) -> None: async def handle_target_message(tgt: TargetMessage) -> None:
match tgt.WhichOneof("msg"): match tgt.WhichOneof("msg"):
case "echo": case "echo":
await echo_response_queue.put(tgt.echo.data) await echo_response_queue.put(tgt.id)
case "test": case "test":
pass pass
@ -242,7 +242,8 @@ async def message_sender() -> None:
try: try:
while True: while True:
msg = HostMessage() msg = HostMessage()
msg.echo.data = random.randint(0, 2**22) msg.id = random.randint(0, 2**22)
msg.echo.SetInParent()
await outgoing_messages.put(msg) await outgoing_messages.put(msg)
@ -253,10 +254,8 @@ async def message_sender() -> None:
logger.error("Timeout waiting for echo response") # noqa: TRY400 logger.error("Timeout waiting for echo response") # noqa: TRY400
else: else:
if response != msg.echo.data: if response != msg.id:
logger.error( logger.error("Incorrect echo response: expected %d - got %d", msg.id, response)
"Incorrect echo response: expected %d - got %d", msg.echo.data, response
)
await asyncio.sleep(5) await asyncio.sleep(5)

View file

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: test.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\ntest.proto\x12\x04test\">\n\x0cTestResponse\x12\n\n\x02\x66\x31\x18\x01 \x01(\r\x12\n\n\x02\x66\x32\x18\x02 \x01(\t\x12\n\n\x02\x66\x33\x18\x03 \x01(\x08\x12\n\n\x02\x66\x34\x18\x04 \x01(\x0c\x62\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'test_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_TESTRESPONSE._serialized_start=20
_TESTRESPONSE._serialized_end=82
# @@protoc_insertion_point(module_scope)

View file

@ -1,25 +0,0 @@
from typing import ClassVar as _ClassVar
from typing import Optional as _Optional
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
DESCRIPTOR: _descriptor.FileDescriptor
class TestResponse(_message.Message):
__slots__ = ["f1", "f2", "f3", "f4"]
F1_FIELD_NUMBER: _ClassVar[int]
F2_FIELD_NUMBER: _ClassVar[int]
F3_FIELD_NUMBER: _ClassVar[int]
F4_FIELD_NUMBER: _ClassVar[int]
f1: int
f2: str
f3: bool
f4: bytes
def __init__(
self,
f1: int | None = ...,
f2: str | None = ...,
f3: bool = ...,
f4: bytes | None = ...,
) -> None: ...