Compare commits

..

No commits in common. "22baa4a18c14c8067935063b53cdf2f0bc1b991a" and "598e22f337bda39520683c5c3fb0a8991feda357" have entirely different histories.

14 changed files with 481 additions and 160 deletions

View file

@ -1,7 +1,7 @@
use std::env;
use std::path::Path;
use micropb_gen::Generator;
use micropb_gen::{Config, Generator};
fn proto_generate() {
let firmware_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
@ -14,9 +14,15 @@ fn proto_generate() {
let mut g = Generator::new();
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()))
.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"),
)
.unwrap();

View file

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

View file

@ -1,18 +1,46 @@
pub mod echo_ {
#[derive(Debug, Clone)]
pub struct EchoRequest {}
pub struct EchoRequest {
pub r#data: u32,
}
impl ::core::default::Default for EchoRequest {
fn default() -> Self {
Self {}
Self {
r#data: ::core::default::Default::default(),
}
}
}
impl ::core::cmp::PartialEq for EchoRequest {
fn eq(&self, other: &Self) -> bool {
let mut ret = true;
ret &= (self.r#data == other.r#data);
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 {
fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>(
&mut self,
@ -25,6 +53,16 @@ pub mod echo_ {
let tag = decoder.decode_tag()?;
match tag.field_num() {
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())?;
}
@ -39,28 +77,69 @@ pub mod echo_ {
encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>,
) -> Result<(), IMPL_MICROPB_WRITE::Error> {
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(())
}
fn compute_size(&self) -> usize {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
let mut size = 0;
{
let val_ref = &self.r#data;
if *val_ref != 0 {
size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _);
}
}
size
}
}
#[derive(Debug, Clone)]
pub struct EchoResponse {}
pub struct EchoResponse {
pub r#data: u32,
}
impl ::core::default::Default for EchoResponse {
fn default() -> Self {
Self {}
Self {
r#data: ::core::default::Default::default(),
}
}
}
impl ::core::cmp::PartialEq for EchoResponse {
fn eq(&self, other: &Self) -> bool {
let mut ret = true;
ret &= (self.r#data == other.r#data);
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 {
fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>(
&mut self,
@ -73,6 +152,16 @@ pub mod echo_ {
let tag = decoder.decode_tag()?;
match tag.field_num() {
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())?;
}
@ -87,11 +176,263 @@ pub mod echo_ {
encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>,
) -> Result<(), IMPL_MICROPB_WRITE::Error> {
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(())
}
fn compute_size(&self) -> usize {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
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
}
}
@ -105,13 +446,11 @@ pub mod api_ {
}
#[derive(Debug, Clone)]
pub struct HostMessage {
pub r#id: u32,
pub r#msg: ::core::option::Option<HostMessage_::Msg>,
}
impl ::core::default::Default for HostMessage {
fn default() -> Self {
Self {
r#id: ::core::default::Default::default(),
r#msg: ::core::default::Default::default(),
}
}
@ -119,35 +458,11 @@ pub mod api_ {
impl ::core::cmp::PartialEq for HostMessage {
fn eq(&self, other: &Self) -> bool {
let mut ret = true;
ret &= (self.r#id == other.r#id);
ret &= (self.r#msg == other.r#msg);
ret
}
}
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 HostMessage {}
impl ::micropb::MessageDecode for HostMessage {
fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>(
&mut self,
@ -161,16 +476,6 @@ pub mod api_ {
match tag.field_num() {
0 => return Err(::micropb::DecodeError::ZeroField),
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 {
if let ::core::option::Option::Some(variant) = &mut self
.r#msg
@ -199,18 +504,11 @@ pub mod api_ {
encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>,
) -> Result<(), IMPL_MICROPB_WRITE::Error> {
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 {
match &*oneof {
HostMessage_::Msg::Echo(val_ref) => {
let val_ref = &*val_ref;
encoder.encode_varint32(18u32)?;
encoder.encode_varint32(10u32)?;
val_ref.encode_len_delimited(encoder)?;
}
}
@ -220,12 +518,6 @@ pub mod api_ {
fn compute_size(&self) -> usize {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
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 {
match &*oneof {
HostMessage_::Msg::Echo(val_ref) => {
@ -245,17 +537,16 @@ pub mod api_ {
#[derive(Debug, PartialEq, Clone)]
pub enum Msg {
Echo(super::super::echo_::EchoResponse),
Test(super::super::test_::TestResponse),
}
}
#[derive(Debug, Clone)]
pub struct TargetMessage {
pub r#id: u32,
pub r#msg: ::core::option::Option<TargetMessage_::Msg>,
}
impl ::core::default::Default for TargetMessage {
fn default() -> Self {
Self {
r#id: ::core::default::Default::default(),
r#msg: ::core::default::Default::default(),
}
}
@ -263,35 +554,11 @@ pub mod api_ {
impl ::core::cmp::PartialEq for TargetMessage {
fn eq(&self, other: &Self) -> bool {
let mut ret = true;
ret &= (self.r#id == other.r#id);
ret &= (self.r#msg == other.r#msg);
ret
}
}
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 TargetMessage {}
impl ::micropb::MessageDecode for TargetMessage {
fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>(
&mut self,
@ -305,16 +572,6 @@ pub mod api_ {
match tag.field_num() {
0 => return Err(::micropb::DecodeError::ZeroField),
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 {
if let ::core::option::Option::Some(variant) = &mut self
.r#msg
@ -331,6 +588,23 @@ pub mod api_ {
};
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())?;
}
@ -345,16 +619,14 @@ pub mod api_ {
encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>,
) -> Result<(), IMPL_MICROPB_WRITE::Error> {
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 {
match &*oneof {
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;
encoder.encode_varint32(18u32)?;
val_ref.encode_len_delimited(encoder)?;
@ -366,12 +638,6 @@ pub mod api_ {
fn compute_size(&self) -> usize {
use ::micropb::{PbVec, PbMap, PbString, FieldEncode};
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 {
match &*oneof {
TargetMessage_::Msg::Echo(val_ref) => {
@ -382,6 +648,14 @@ pub mod api_ {
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

View file

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

View file

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

View file

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

10
proto/test.proto Normal file
View file

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

View file

@ -12,17 +12,18 @@ _sym_db = _symbol_database.Default()
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\"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')
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')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'api_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_HOSTMESSAGE._serialized_start=30
_HOSTMESSAGE._serialized_start=42
_HOSTMESSAGE._serialized_end=97
_TARGETMESSAGE._serialized_start=99
_TARGETMESSAGE._serialized_end=169
_TARGETMESSAGE._serialized_end=193
# @@protoc_insertion_point(module_scope)

View file

@ -1,4 +1,5 @@
import echo_pb2 as _echo_pb2
import test_pb2 as _test_pb2
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
@ -6,17 +7,15 @@ from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Opti
DESCRIPTOR: _descriptor.FileDescriptor
class HostMessage(_message.Message):
__slots__ = ["echo", "id"]
__slots__ = ["echo"]
ECHO_FIELD_NUMBER: _ClassVar[int]
ID_FIELD_NUMBER: _ClassVar[int]
echo: _echo_pb2.EchoRequest
id: int
def __init__(self, id: _Optional[int] = ..., echo: _Optional[_Union[_echo_pb2.EchoRequest, _Mapping]] = ...) -> None: ...
def __init__(self, echo: _Optional[_Union[_echo_pb2.EchoRequest, _Mapping]] = ...) -> None: ...
class TargetMessage(_message.Message):
__slots__ = ["echo", "id"]
__slots__ = ["echo", "test"]
ECHO_FIELD_NUMBER: _ClassVar[int]
ID_FIELD_NUMBER: _ClassVar[int]
TEST_FIELD_NUMBER: _ClassVar[int]
echo: _echo_pb2.EchoResponse
id: int
def __init__(self, id: _Optional[int] = ..., echo: _Optional[_Union[_echo_pb2.EchoResponse, _Mapping]] = ...) -> None: ...
test: _test_pb2.TestResponse
def __init__(self, echo: _Optional[_Union[_echo_pb2.EchoResponse, _Mapping]] = ..., test: _Optional[_Union[_test_pb2.TestResponse, _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\"\r\n\x0b\x45\x63hoRequest\"\x0e\n\x0c\x45\x63hoResponseb\x06proto3')
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')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'echo_pb2', globals())
@ -21,7 +21,7 @@ if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_ECHOREQUEST._serialized_start=20
_ECHOREQUEST._serialized_end=33
_ECHORESPONSE._serialized_start=35
_ECHORESPONSE._serialized_end=49
_ECHOREQUEST._serialized_end=47
_ECHORESPONSE._serialized_start=49
_ECHORESPONSE._serialized_end=77
# @@protoc_insertion_point(module_scope)

View file

@ -1,13 +1,17 @@
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from typing import ClassVar as _ClassVar
from typing import ClassVar as _ClassVar, Optional as _Optional
DESCRIPTOR: _descriptor.FileDescriptor
class EchoRequest(_message.Message):
__slots__ = []
def __init__(self) -> None: ...
__slots__ = ["data"]
DATA_FIELD_NUMBER: _ClassVar[int]
data: int
def __init__(self, data: _Optional[int] = ...) -> None: ...
class EchoResponse(_message.Message):
__slots__ = []
def __init__(self) -> None: ...
__slots__ = ["data"]
DATA_FIELD_NUMBER: _ClassVar[int]
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:
match tgt.WhichOneof("msg"):
case "echo":
await echo_response_queue.put(tgt.id)
await echo_response_queue.put(tgt.echo.data)
case "test":
pass
@ -242,8 +242,7 @@ async def message_sender() -> None:
try:
while True:
msg = HostMessage()
msg.id = random.randint(0, 2**22)
msg.echo.SetInParent()
msg.echo.data = random.randint(0, 2**22)
await outgoing_messages.put(msg)
@ -254,8 +253,10 @@ async def message_sender() -> None:
logger.error("Timeout waiting for echo response") # noqa: TRY400
else:
if response != msg.id:
logger.error("Incorrect echo response: expected %d - got %d", msg.id, response)
if response != msg.echo.data:
logger.error(
"Incorrect echo response: expected %d - got %d", msg.echo.data, response
)
await asyncio.sleep(5)

25
prototest/test_pb2.py Normal file
View file

@ -0,0 +1,25 @@
# -*- 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)

25
prototest/test_pb2.pyi Normal file
View file

@ -0,0 +1,25 @@
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: ...