All in one solution demonstrating how to use nanopb Protocol Buffers library from within mbed environment. Test case is very simple. It works.

Dependencies:   nanopb protocol

Original import was an all-in-one solution that only depends on mbed.

Current implementation extracted 2 librarires:

1) nanopb contains code required to use nanopb and Timestamp dependency. 2) protocol is a specific research protocol used by LCE at Itron at the moment of commit.

The application decodes Protocol Buffers message generated with GO application using the same 'protocol'. This test level application decodes message and validates that it matches expected.

It is simply a proof that nanopb library can be used.

Committer:
sgnezdov
Date:
Wed Jul 12 22:40:29 2017 +0000
Revision:
0:fbdd0d307c19
initial import demonstrates how to decode Sample protocol buffers message.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sgnezdov 0:fbdd0d307c19 1 /* pb_common.c: Common support functions for pb_encode.c and pb_decode.c.
sgnezdov 0:fbdd0d307c19 2 *
sgnezdov 0:fbdd0d307c19 3 * 2014 Petteri Aimonen <jpa@kapsi.fi>
sgnezdov 0:fbdd0d307c19 4 */
sgnezdov 0:fbdd0d307c19 5
sgnezdov 0:fbdd0d307c19 6 #include "pb_common.h"
sgnezdov 0:fbdd0d307c19 7
sgnezdov 0:fbdd0d307c19 8 bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct)
sgnezdov 0:fbdd0d307c19 9 {
sgnezdov 0:fbdd0d307c19 10 iter->start = fields;
sgnezdov 0:fbdd0d307c19 11 iter->pos = fields;
sgnezdov 0:fbdd0d307c19 12 iter->required_field_index = 0;
sgnezdov 0:fbdd0d307c19 13 iter->dest_struct = dest_struct;
sgnezdov 0:fbdd0d307c19 14 iter->pData = (char*)dest_struct + iter->pos->data_offset;
sgnezdov 0:fbdd0d307c19 15 iter->pSize = (char*)iter->pData + iter->pos->size_offset;
sgnezdov 0:fbdd0d307c19 16
sgnezdov 0:fbdd0d307c19 17 return (iter->pos->tag != 0);
sgnezdov 0:fbdd0d307c19 18 }
sgnezdov 0:fbdd0d307c19 19
sgnezdov 0:fbdd0d307c19 20 bool pb_field_iter_next(pb_field_iter_t *iter)
sgnezdov 0:fbdd0d307c19 21 {
sgnezdov 0:fbdd0d307c19 22 const pb_field_t *prev_field = iter->pos;
sgnezdov 0:fbdd0d307c19 23
sgnezdov 0:fbdd0d307c19 24 if (prev_field->tag == 0)
sgnezdov 0:fbdd0d307c19 25 {
sgnezdov 0:fbdd0d307c19 26 /* Handle empty message types, where the first field is already the terminator.
sgnezdov 0:fbdd0d307c19 27 * In other cases, the iter->pos never points to the terminator. */
sgnezdov 0:fbdd0d307c19 28 return false;
sgnezdov 0:fbdd0d307c19 29 }
sgnezdov 0:fbdd0d307c19 30
sgnezdov 0:fbdd0d307c19 31 iter->pos++;
sgnezdov 0:fbdd0d307c19 32
sgnezdov 0:fbdd0d307c19 33 if (iter->pos->tag == 0)
sgnezdov 0:fbdd0d307c19 34 {
sgnezdov 0:fbdd0d307c19 35 /* Wrapped back to beginning, reinitialize */
sgnezdov 0:fbdd0d307c19 36 (void)pb_field_iter_begin(iter, iter->start, iter->dest_struct);
sgnezdov 0:fbdd0d307c19 37 return false;
sgnezdov 0:fbdd0d307c19 38 }
sgnezdov 0:fbdd0d307c19 39 else
sgnezdov 0:fbdd0d307c19 40 {
sgnezdov 0:fbdd0d307c19 41 /* Increment the pointers based on previous field size */
sgnezdov 0:fbdd0d307c19 42 size_t prev_size = prev_field->data_size;
sgnezdov 0:fbdd0d307c19 43
sgnezdov 0:fbdd0d307c19 44 if (PB_HTYPE(prev_field->type) == PB_HTYPE_ONEOF &&
sgnezdov 0:fbdd0d307c19 45 PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF &&
sgnezdov 0:fbdd0d307c19 46 iter->pos->data_offset == PB_SIZE_MAX)
sgnezdov 0:fbdd0d307c19 47 {
sgnezdov 0:fbdd0d307c19 48 /* Don't advance pointers inside unions */
sgnezdov 0:fbdd0d307c19 49 return true;
sgnezdov 0:fbdd0d307c19 50 }
sgnezdov 0:fbdd0d307c19 51 else if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC &&
sgnezdov 0:fbdd0d307c19 52 PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED)
sgnezdov 0:fbdd0d307c19 53 {
sgnezdov 0:fbdd0d307c19 54 /* In static arrays, the data_size tells the size of a single entry and
sgnezdov 0:fbdd0d307c19 55 * array_size is the number of entries */
sgnezdov 0:fbdd0d307c19 56 prev_size *= prev_field->array_size;
sgnezdov 0:fbdd0d307c19 57 }
sgnezdov 0:fbdd0d307c19 58 else if (PB_ATYPE(prev_field->type) == PB_ATYPE_POINTER)
sgnezdov 0:fbdd0d307c19 59 {
sgnezdov 0:fbdd0d307c19 60 /* Pointer fields always have a constant size in the main structure.
sgnezdov 0:fbdd0d307c19 61 * The data_size only applies to the dynamically allocated area. */
sgnezdov 0:fbdd0d307c19 62 prev_size = sizeof(void*);
sgnezdov 0:fbdd0d307c19 63 }
sgnezdov 0:fbdd0d307c19 64
sgnezdov 0:fbdd0d307c19 65 if (PB_HTYPE(prev_field->type) == PB_HTYPE_REQUIRED)
sgnezdov 0:fbdd0d307c19 66 {
sgnezdov 0:fbdd0d307c19 67 /* Count the required fields, in order to check their presence in the
sgnezdov 0:fbdd0d307c19 68 * decoder. */
sgnezdov 0:fbdd0d307c19 69 iter->required_field_index++;
sgnezdov 0:fbdd0d307c19 70 }
sgnezdov 0:fbdd0d307c19 71
sgnezdov 0:fbdd0d307c19 72 iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset;
sgnezdov 0:fbdd0d307c19 73 iter->pSize = (char*)iter->pData + iter->pos->size_offset;
sgnezdov 0:fbdd0d307c19 74 return true;
sgnezdov 0:fbdd0d307c19 75 }
sgnezdov 0:fbdd0d307c19 76 }
sgnezdov 0:fbdd0d307c19 77
sgnezdov 0:fbdd0d307c19 78 bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag)
sgnezdov 0:fbdd0d307c19 79 {
sgnezdov 0:fbdd0d307c19 80 const pb_field_t *start = iter->pos;
sgnezdov 0:fbdd0d307c19 81
sgnezdov 0:fbdd0d307c19 82 do {
sgnezdov 0:fbdd0d307c19 83 if (iter->pos->tag == tag &&
sgnezdov 0:fbdd0d307c19 84 PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION)
sgnezdov 0:fbdd0d307c19 85 {
sgnezdov 0:fbdd0d307c19 86 /* Found the wanted field */
sgnezdov 0:fbdd0d307c19 87 return true;
sgnezdov 0:fbdd0d307c19 88 }
sgnezdov 0:fbdd0d307c19 89
sgnezdov 0:fbdd0d307c19 90 (void)pb_field_iter_next(iter);
sgnezdov 0:fbdd0d307c19 91 } while (iter->pos != start);
sgnezdov 0:fbdd0d307c19 92
sgnezdov 0:fbdd0d307c19 93 /* Searched all the way back to start, and found nothing. */
sgnezdov 0:fbdd0d307c19 94 return false;
sgnezdov 0:fbdd0d307c19 95 }
sgnezdov 0:fbdd0d307c19 96
sgnezdov 0:fbdd0d307c19 97