Hi,
If you are using pb_istream_from_buffer(), you can get the pointer to
the data from stream.state. In a submessage callback, the length of the
stream is the length of the message data.
Using 0.4.x style callbacks I would do it this way:
message SignedCommand {
required Command command = 1
[(nanopb).type = FT_CALLBACK,
(nanopb).callback_datatype = "struct location_t { uint8_t *start; uint32_t len; }",
(nanopb).callback_function = "SignedCommand_Command_callback"
];
required bytes sha256_signature = 2
[(nanopb).max_size = 32, (nanopb).fixed_length = true];
}
bool SignedCommand_Command_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
{
if (istream)
{
// Store the location of data
struct location_t *dest = (struct location_t*)field->pData;
dest->start = (uint8_t*)istream->state;
dest->len = istream->bytes_left;
}
return true;
}
The struct definition in generated .pb.h file will be like this:
typedef struct _SignedCommand {
struct location_t { uint8_t *start; uint32_t len; } command;
pb_byte_t sha256_signature[32];
} SignedCommand;
The callback is bound by name, and the message will have fields
msg.command.start and msg.command.len which are filled in after the
decoding.
You can then proceed to check the hash and after that decode the
submessage by passing the start and length to a new call of
pb_istream_from_buffer().
If you are on 0.3.x or prefer function pointer callbacks, the idea is
the same except you need to use the arg pointer to store the results
somewhere.
--
Petteri