1

I've looked through a number of other posts but none seem to resolve my issue.

I'm using nanoPB in C, creating messages in json and converting them to pb to send to my device.

Given this proto message and options file

message PB_BoundingArray {
    enum Shape {
        INVALID = 0;
        CIRCLE = 1;
        UNUSED = 2;
        TRIANGLE = 3;
        QUADRANGLE = 4;
    }
    Shape type = 1;
    repeated float point_x = 2;
    repeated float point_y = 3;
}

message PB_ConfigurationData {
    uint32 min = 1;
    uint32 max = 2;
    PB_BoundingArray bounds = 3;
}
PB_BoundingArray.point_x max_count:4
PB_BoundingArray.point_x fixed_count:true
PB_BoundingArray.point_y max_count:4
PB_BoundingArray.point_y fixed_count:true
PB_ConfigurationData.bounds max_count:10
PB_ConfigurationData.bounds fixed_count:true

I'll create a json file that looks like this:

{
    "bounds":
    [
        {
            "point_x":
            [
                39.845129,
                39.840504,
                39.840420,
                39.845119
            ],
            "point_y":
            [
                -102.126389,
                -102.126111,
                -102.118611,
                -102.118611
            ],
            "type": "QUADRANGLE"
        }
    ],
    "max": 90000,
    "min": 10800
}

And use a python script and serialize it into protobuf (truncated for berevity)

from lib.length_delimited_protobuf import serialize, deserialize
...
elif args.json_file:
    with open(args.json_file, "r") as input_file:
        message = Parse(input_file.read(), message_type)
        sys.stdout.buffer.write(serialize(message))
...

The standard output is redirected to a file so it's saved. If I give that file to my C function

// where buffer is char buffer from a raw read of the .pb file
pb_istream_t stream = pb_istream_from_buffer(buffer, bytesRead);
if(!pb_decode_delimited(&stream, PB_ConfigurationData_fields, &current))
{
    // error handling
}

The pb_decode_delimited call fails if bounds is populated in the .pb file with the error message parent stream too short.

I don't fully understand why there is not enough data in the stream. I believe the message to be encoded correctly as I can deserialize it in python. My suspicion is there is a flag or some option that needs to be set so I can properly have a repeated sub message with repeated fields within.

ch701x
  • 21
  • 2
  • Try verifying the value of `bytesRead` and contents of the `buffer` on the C side. Then you can use e.g. https://protogen.marcgravell.com/decode to check if it valid. If you are using Windows the PC, also verify that the streams are set to binary mode. – jpa Oct 20 '21 at 06:22
  • Can you elaborate how you transfer the data from python to your embedded target? – Bart Oct 20 '21 at 06:24
  • @jpa I can output the buffer but when I press decode on the site you linked, nothing happens. I'm not sure if there's an error decoding it or not since there's no output. – ch701x Oct 20 '21 at 13:19
  • @Bart Right now I'm doing unit tests, so I'm passing in a local .pb file. – ch701x Oct 20 '21 at 13:23
  • On what platform are you running unit tests? You can also include hex dump of the data in your question. – jpa Oct 20 '21 at 14:00

1 Answers1

1

I found my issue. I was unaware of a max buffer size set elsewhere in the code base that was limiting the buffer size to 64 and some of my messages were 117+ characters long. Therefore they couldn't be decoded.

ch701x
  • 21
  • 2