1*c8d645caSAndroid Build Coastguard Worker====================== 2*c8d645caSAndroid Build Coastguard WorkerNanopb: Basic concepts 3*c8d645caSAndroid Build Coastguard Worker====================== 4*c8d645caSAndroid Build Coastguard Worker 5*c8d645caSAndroid Build Coastguard Worker.. include :: menu.rst 6*c8d645caSAndroid Build Coastguard Worker 7*c8d645caSAndroid Build Coastguard WorkerThe things outlined here are the underlying concepts of the nanopb design. 8*c8d645caSAndroid Build Coastguard Worker 9*c8d645caSAndroid Build Coastguard Worker.. contents:: 10*c8d645caSAndroid Build Coastguard Worker 11*c8d645caSAndroid Build Coastguard WorkerProto files 12*c8d645caSAndroid Build Coastguard Worker=========== 13*c8d645caSAndroid Build Coastguard WorkerAll Protocol Buffers implementations use .proto files to describe the message 14*c8d645caSAndroid Build Coastguard Workerformat. The point of these files is to be a portable interface description 15*c8d645caSAndroid Build Coastguard Workerlanguage. 16*c8d645caSAndroid Build Coastguard Worker 17*c8d645caSAndroid Build Coastguard WorkerCompiling .proto files for nanopb 18*c8d645caSAndroid Build Coastguard Worker--------------------------------- 19*c8d645caSAndroid Build Coastguard WorkerNanopb uses the Google's protoc compiler to parse the .proto file, and then a 20*c8d645caSAndroid Build Coastguard Workerpython script to generate the C header and source code from it:: 21*c8d645caSAndroid Build Coastguard Worker 22*c8d645caSAndroid Build Coastguard Worker user@host:~$ protoc -omessage.pb message.proto 23*c8d645caSAndroid Build Coastguard Worker user@host:~$ python ../generator/nanopb_generator.py message.pb 24*c8d645caSAndroid Build Coastguard Worker Writing to message.h and message.c 25*c8d645caSAndroid Build Coastguard Worker user@host:~$ 26*c8d645caSAndroid Build Coastguard Worker 27*c8d645caSAndroid Build Coastguard WorkerModifying generator behaviour 28*c8d645caSAndroid Build Coastguard Worker----------------------------- 29*c8d645caSAndroid Build Coastguard WorkerUsing generator options, you can set maximum sizes for fields in order to 30*c8d645caSAndroid Build Coastguard Workerallocate them statically. The preferred way to do this is to create an .options 31*c8d645caSAndroid Build Coastguard Workerfile with the same name as your .proto file:: 32*c8d645caSAndroid Build Coastguard Worker 33*c8d645caSAndroid Build Coastguard Worker # Foo.proto 34*c8d645caSAndroid Build Coastguard Worker message Foo { 35*c8d645caSAndroid Build Coastguard Worker required string name = 1; 36*c8d645caSAndroid Build Coastguard Worker } 37*c8d645caSAndroid Build Coastguard Worker 38*c8d645caSAndroid Build Coastguard Worker:: 39*c8d645caSAndroid Build Coastguard Worker 40*c8d645caSAndroid Build Coastguard Worker # Foo.options 41*c8d645caSAndroid Build Coastguard Worker Foo.name max_size:16 42*c8d645caSAndroid Build Coastguard Worker 43*c8d645caSAndroid Build Coastguard WorkerFor more information on this, see the `Proto file options`_ section in the 44*c8d645caSAndroid Build Coastguard Workerreference manual. 45*c8d645caSAndroid Build Coastguard Worker 46*c8d645caSAndroid Build Coastguard Worker.. _`Proto file options`: reference.html#proto-file-options 47*c8d645caSAndroid Build Coastguard Worker 48*c8d645caSAndroid Build Coastguard WorkerStreams 49*c8d645caSAndroid Build Coastguard Worker======= 50*c8d645caSAndroid Build Coastguard Worker 51*c8d645caSAndroid Build Coastguard WorkerNanopb uses streams for accessing the data in encoded format. 52*c8d645caSAndroid Build Coastguard WorkerThe stream abstraction is very lightweight, and consists of a structure (*pb_ostream_t* or *pb_istream_t*) which contains a pointer to a callback function. 53*c8d645caSAndroid Build Coastguard Worker 54*c8d645caSAndroid Build Coastguard WorkerThere are a few generic rules for callback functions: 55*c8d645caSAndroid Build Coastguard Worker 56*c8d645caSAndroid Build Coastguard Worker#) Return false on IO errors. The encoding or decoding process will abort immediately. 57*c8d645caSAndroid Build Coastguard Worker#) Use state to store your own data, such as a file descriptor. 58*c8d645caSAndroid Build Coastguard Worker#) *bytes_written* and *bytes_left* are updated by pb_write and pb_read. 59*c8d645caSAndroid Build Coastguard Worker#) Your callback may be used with substreams. In this case *bytes_left*, *bytes_written* and *max_size* have smaller values than the original stream. Don't use these values to calculate pointers. 60*c8d645caSAndroid Build Coastguard Worker#) Always read or write the full requested length of data. For example, POSIX *recv()* needs the *MSG_WAITALL* parameter to accomplish this. 61*c8d645caSAndroid Build Coastguard Worker 62*c8d645caSAndroid Build Coastguard WorkerOutput streams 63*c8d645caSAndroid Build Coastguard Worker-------------- 64*c8d645caSAndroid Build Coastguard Worker 65*c8d645caSAndroid Build Coastguard Worker:: 66*c8d645caSAndroid Build Coastguard Worker 67*c8d645caSAndroid Build Coastguard Worker struct _pb_ostream_t 68*c8d645caSAndroid Build Coastguard Worker { 69*c8d645caSAndroid Build Coastguard Worker bool (*callback)(pb_ostream_t *stream, const uint8_t *buf, size_t count); 70*c8d645caSAndroid Build Coastguard Worker void *state; 71*c8d645caSAndroid Build Coastguard Worker size_t max_size; 72*c8d645caSAndroid Build Coastguard Worker size_t bytes_written; 73*c8d645caSAndroid Build Coastguard Worker }; 74*c8d645caSAndroid Build Coastguard Worker 75*c8d645caSAndroid Build Coastguard WorkerThe *callback* for output stream may be NULL, in which case the stream simply counts the number of bytes written. In this case, *max_size* is ignored. 76*c8d645caSAndroid Build Coastguard Worker 77*c8d645caSAndroid Build Coastguard WorkerOtherwise, if *bytes_written* + bytes_to_be_written is larger than *max_size*, pb_write returns false before doing anything else. If you don't want to limit the size of the stream, pass SIZE_MAX. 78*c8d645caSAndroid Build Coastguard Worker 79*c8d645caSAndroid Build Coastguard Worker**Example 1:** 80*c8d645caSAndroid Build Coastguard Worker 81*c8d645caSAndroid Build Coastguard WorkerThis is the way to get the size of the message without storing it anywhere:: 82*c8d645caSAndroid Build Coastguard Worker 83*c8d645caSAndroid Build Coastguard Worker Person myperson = ...; 84*c8d645caSAndroid Build Coastguard Worker pb_ostream_t sizestream = {0}; 85*c8d645caSAndroid Build Coastguard Worker pb_encode(&sizestream, Person_fields, &myperson); 86*c8d645caSAndroid Build Coastguard Worker printf("Encoded size is %d\n", sizestream.bytes_written); 87*c8d645caSAndroid Build Coastguard Worker 88*c8d645caSAndroid Build Coastguard Worker**Example 2:** 89*c8d645caSAndroid Build Coastguard Worker 90*c8d645caSAndroid Build Coastguard WorkerWriting to stdout:: 91*c8d645caSAndroid Build Coastguard Worker 92*c8d645caSAndroid Build Coastguard Worker bool callback(pb_ostream_t *stream, const uint8_t *buf, size_t count) 93*c8d645caSAndroid Build Coastguard Worker { 94*c8d645caSAndroid Build Coastguard Worker FILE *file = (FILE*) stream->state; 95*c8d645caSAndroid Build Coastguard Worker return fwrite(buf, 1, count, file) == count; 96*c8d645caSAndroid Build Coastguard Worker } 97*c8d645caSAndroid Build Coastguard Worker 98*c8d645caSAndroid Build Coastguard Worker pb_ostream_t stdoutstream = {&callback, stdout, SIZE_MAX, 0}; 99*c8d645caSAndroid Build Coastguard Worker 100*c8d645caSAndroid Build Coastguard WorkerInput streams 101*c8d645caSAndroid Build Coastguard Worker------------- 102*c8d645caSAndroid Build Coastguard WorkerFor input streams, there is one extra rule: 103*c8d645caSAndroid Build Coastguard Worker 104*c8d645caSAndroid Build Coastguard Worker#) You don't need to know the length of the message in advance. After getting EOF error when reading, set bytes_left to 0 and return false. Pb_decode will detect this and if the EOF was in a proper position, it will return true. 105*c8d645caSAndroid Build Coastguard Worker 106*c8d645caSAndroid Build Coastguard WorkerHere is the structure:: 107*c8d645caSAndroid Build Coastguard Worker 108*c8d645caSAndroid Build Coastguard Worker struct _pb_istream_t 109*c8d645caSAndroid Build Coastguard Worker { 110*c8d645caSAndroid Build Coastguard Worker bool (*callback)(pb_istream_t *stream, uint8_t *buf, size_t count); 111*c8d645caSAndroid Build Coastguard Worker void *state; 112*c8d645caSAndroid Build Coastguard Worker size_t bytes_left; 113*c8d645caSAndroid Build Coastguard Worker }; 114*c8d645caSAndroid Build Coastguard Worker 115*c8d645caSAndroid Build Coastguard WorkerThe *callback* must always be a function pointer. *Bytes_left* is an upper limit on the number of bytes that will be read. You can use SIZE_MAX if your callback handles EOF as described above. 116*c8d645caSAndroid Build Coastguard Worker 117*c8d645caSAndroid Build Coastguard Worker**Example:** 118*c8d645caSAndroid Build Coastguard Worker 119*c8d645caSAndroid Build Coastguard WorkerThis function binds an input stream to stdin: 120*c8d645caSAndroid Build Coastguard Worker 121*c8d645caSAndroid Build Coastguard Worker:: 122*c8d645caSAndroid Build Coastguard Worker 123*c8d645caSAndroid Build Coastguard Worker bool callback(pb_istream_t *stream, uint8_t *buf, size_t count) 124*c8d645caSAndroid Build Coastguard Worker { 125*c8d645caSAndroid Build Coastguard Worker FILE *file = (FILE*)stream->state; 126*c8d645caSAndroid Build Coastguard Worker bool status; 127*c8d645caSAndroid Build Coastguard Worker 128*c8d645caSAndroid Build Coastguard Worker if (buf == NULL) 129*c8d645caSAndroid Build Coastguard Worker { 130*c8d645caSAndroid Build Coastguard Worker while (count-- && fgetc(file) != EOF); 131*c8d645caSAndroid Build Coastguard Worker return count == 0; 132*c8d645caSAndroid Build Coastguard Worker } 133*c8d645caSAndroid Build Coastguard Worker 134*c8d645caSAndroid Build Coastguard Worker status = (fread(buf, 1, count, file) == count); 135*c8d645caSAndroid Build Coastguard Worker 136*c8d645caSAndroid Build Coastguard Worker if (feof(file)) 137*c8d645caSAndroid Build Coastguard Worker stream->bytes_left = 0; 138*c8d645caSAndroid Build Coastguard Worker 139*c8d645caSAndroid Build Coastguard Worker return status; 140*c8d645caSAndroid Build Coastguard Worker } 141*c8d645caSAndroid Build Coastguard Worker 142*c8d645caSAndroid Build Coastguard Worker pb_istream_t stdinstream = {&callback, stdin, SIZE_MAX}; 143*c8d645caSAndroid Build Coastguard Worker 144*c8d645caSAndroid Build Coastguard WorkerData types 145*c8d645caSAndroid Build Coastguard Worker========== 146*c8d645caSAndroid Build Coastguard Worker 147*c8d645caSAndroid Build Coastguard WorkerMost Protocol Buffers datatypes have directly corresponding C datatypes, such as int32 is int32_t, float is float and bool is bool. However, the variable-length datatypes are more complex: 148*c8d645caSAndroid Build Coastguard Worker 149*c8d645caSAndroid Build Coastguard Worker1) Strings, bytes and repeated fields of any type map to callback functions by default. 150*c8d645caSAndroid Build Coastguard Worker2) If there is a special option *(nanopb).max_size* specified in the .proto file, string maps to null-terminated char array and bytes map to a structure containing a char array and a size field. 151*c8d645caSAndroid Build Coastguard Worker3) If *(nanopb).fixed_length* is set to *true* and *(nanopb).max_size* is also set, then bytes map to an inline byte array of fixed size. 152*c8d645caSAndroid Build Coastguard Worker4) If there is a special option *(nanopb).max_count* specified on a repeated field, it maps to an array of whatever type is being repeated. Another field will be created for the actual number of entries stored. 153*c8d645caSAndroid Build Coastguard Worker5) If *(nanopb).fixed_count* is set to *true* and *(nanopb).max_count* is also set, the field for the actual number of entries will not by created as the count is always assumed to be max count. 154*c8d645caSAndroid Build Coastguard Worker 155*c8d645caSAndroid Build Coastguard Worker=============================================================================== ======================= 156*c8d645caSAndroid Build Coastguard Worker field in .proto autogenerated in .h 157*c8d645caSAndroid Build Coastguard Worker=============================================================================== ======================= 158*c8d645caSAndroid Build Coastguard Workerrequired string name = 1; pb_callback_t name; 159*c8d645caSAndroid Build Coastguard Workerrequired string name = 1 [(nanopb).max_size = 40]; char name[40]; 160*c8d645caSAndroid Build Coastguard Workerrepeated string name = 1 [(nanopb).max_size = 40]; pb_callback_t name; 161*c8d645caSAndroid Build Coastguard Workerrepeated string name = 1 [(nanopb).max_size = 40, (nanopb).max_count = 5]; | size_t name_count; 162*c8d645caSAndroid Build Coastguard Worker | char name[5][40]; 163*c8d645caSAndroid Build Coastguard Workerrequired bytes data = 1 [(nanopb).max_size = 40]; | typedef struct { 164*c8d645caSAndroid Build Coastguard Worker | size_t size; 165*c8d645caSAndroid Build Coastguard Worker | pb_byte_t bytes[40]; 166*c8d645caSAndroid Build Coastguard Worker | } Person_data_t; 167*c8d645caSAndroid Build Coastguard Worker | Person_data_t data; 168*c8d645caSAndroid Build Coastguard Workerrequired bytes data = 1 [(nanopb).max_size = 40, (nanopb).fixed_length = true]; | pb_byte_t data[40]; 169*c8d645caSAndroid Build Coastguard Workerrepeated int32 data = 1 [(nanopb).max_count = 5, (nanopb).fixed_count true]; | int32_t data[5]; 170*c8d645caSAndroid Build Coastguard Worker=============================================================================== ======================= 171*c8d645caSAndroid Build Coastguard Worker 172*c8d645caSAndroid Build Coastguard WorkerThe maximum lengths are checked in runtime. If string/bytes/array exceeds the allocated length, *pb_decode* will return false. 173*c8d645caSAndroid Build Coastguard Worker 174*c8d645caSAndroid Build Coastguard WorkerNote: For the *bytes* datatype, the field length checking may not be exact. 175*c8d645caSAndroid Build Coastguard WorkerThe compiler may add some padding to the *pb_bytes_t* structure, and the nanopb runtime doesn't know how much of the structure size is padding. Therefore it uses the whole length of the structure for storing data, which is not very smart but shouldn't cause problems. In practise, this means that if you specify *(nanopb).max_size=5* on a *bytes* field, you may be able to store 6 bytes there. For the *string* field type, the length limit is exact. 176*c8d645caSAndroid Build Coastguard Worker 177*c8d645caSAndroid Build Coastguard WorkerNote: When using the *fixed_count* option, the decoder assumes the repeated elements are 178*c8d645caSAndroid Build Coastguard Workerreceived sequentially or that repeated elements for a non-packed field will not be interleaved with 179*c8d645caSAndroid Build Coastguard Workeranother *fixed_count* non-packed field. 180*c8d645caSAndroid Build Coastguard Worker 181*c8d645caSAndroid Build Coastguard WorkerField callbacks 182*c8d645caSAndroid Build Coastguard Worker=============== 183*c8d645caSAndroid Build Coastguard WorkerWhen a field has dynamic length, nanopb cannot statically allocate storage for it. Instead, it allows you to handle the field in whatever way you want, using a callback function. 184*c8d645caSAndroid Build Coastguard Worker 185*c8d645caSAndroid Build Coastguard WorkerThe `pb_callback_t`_ structure contains a function pointer and a *void* pointer called *arg* you can use for passing data to the callback. If the function pointer is NULL, the field will be skipped. A pointer to the *arg* is passed to the function, so that it can modify it and retrieve the value. 186*c8d645caSAndroid Build Coastguard Worker 187*c8d645caSAndroid Build Coastguard WorkerThe actual behavior of the callback function is different in encoding and decoding modes. In encoding mode, the callback is called once and should write out everything, including field tags. In decoding mode, the callback is called repeatedly for every data item. 188*c8d645caSAndroid Build Coastguard Worker 189*c8d645caSAndroid Build Coastguard Worker.. _`pb_callback_t`: reference.html#pb-callback-t 190*c8d645caSAndroid Build Coastguard Worker 191*c8d645caSAndroid Build Coastguard WorkerEncoding callbacks 192*c8d645caSAndroid Build Coastguard Worker------------------ 193*c8d645caSAndroid Build Coastguard Worker:: 194*c8d645caSAndroid Build Coastguard Worker 195*c8d645caSAndroid Build Coastguard Worker bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); 196*c8d645caSAndroid Build Coastguard Worker 197*c8d645caSAndroid Build Coastguard WorkerWhen encoding, the callback should write out complete fields, including the wire type and field number tag. It can write as many or as few fields as it likes. For example, if you want to write out an array as *repeated* field, you should do it all in a single call. 198*c8d645caSAndroid Build Coastguard Worker 199*c8d645caSAndroid Build Coastguard WorkerUsually you can use `pb_encode_tag_for_field`_ to encode the wire type and tag number of the field. However, if you want to encode a repeated field as a packed array, you must call `pb_encode_tag`_ instead to specify a wire type of *PB_WT_STRING*. 200*c8d645caSAndroid Build Coastguard Worker 201*c8d645caSAndroid Build Coastguard WorkerIf the callback is used in a submessage, it will be called multiple times during a single call to `pb_encode`_. In this case, it must produce the same amount of data every time. If the callback is directly in the main message, it is called only once. 202*c8d645caSAndroid Build Coastguard Worker 203*c8d645caSAndroid Build Coastguard Worker.. _`pb_encode`: reference.html#pb-encode 204*c8d645caSAndroid Build Coastguard Worker.. _`pb_encode_tag_for_field`: reference.html#pb-encode-tag-for-field 205*c8d645caSAndroid Build Coastguard Worker.. _`pb_encode_tag`: reference.html#pb-encode-tag 206*c8d645caSAndroid Build Coastguard Worker 207*c8d645caSAndroid Build Coastguard WorkerThis callback writes out a dynamically sized string:: 208*c8d645caSAndroid Build Coastguard Worker 209*c8d645caSAndroid Build Coastguard Worker bool write_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) 210*c8d645caSAndroid Build Coastguard Worker { 211*c8d645caSAndroid Build Coastguard Worker char *str = get_string_from_somewhere(); 212*c8d645caSAndroid Build Coastguard Worker if (!pb_encode_tag_for_field(stream, field)) 213*c8d645caSAndroid Build Coastguard Worker return false; 214*c8d645caSAndroid Build Coastguard Worker 215*c8d645caSAndroid Build Coastguard Worker return pb_encode_string(stream, (uint8_t*)str, strlen(str)); 216*c8d645caSAndroid Build Coastguard Worker } 217*c8d645caSAndroid Build Coastguard Worker 218*c8d645caSAndroid Build Coastguard WorkerDecoding callbacks 219*c8d645caSAndroid Build Coastguard Worker------------------ 220*c8d645caSAndroid Build Coastguard Worker:: 221*c8d645caSAndroid Build Coastguard Worker 222*c8d645caSAndroid Build Coastguard Worker bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); 223*c8d645caSAndroid Build Coastguard Worker 224*c8d645caSAndroid Build Coastguard WorkerWhen decoding, the callback receives a length-limited substring that reads the contents of a single field. The field tag has already been read. For *string* and *bytes*, the length value has already been parsed, and is available at *stream->bytes_left*. 225*c8d645caSAndroid Build Coastguard Worker 226*c8d645caSAndroid Build Coastguard WorkerThe callback will be called multiple times for repeated fields. For packed fields, you can either read multiple values until the stream ends, or leave it to `pb_decode`_ to call your function over and over until all values have been read. 227*c8d645caSAndroid Build Coastguard Worker 228*c8d645caSAndroid Build Coastguard Worker.. _`pb_decode`: reference.html#pb-decode 229*c8d645caSAndroid Build Coastguard Worker 230*c8d645caSAndroid Build Coastguard WorkerThis callback reads multiple integers and prints them:: 231*c8d645caSAndroid Build Coastguard Worker 232*c8d645caSAndroid Build Coastguard Worker bool read_ints(pb_istream_t *stream, const pb_field_t *field, void **arg) 233*c8d645caSAndroid Build Coastguard Worker { 234*c8d645caSAndroid Build Coastguard Worker while (stream->bytes_left) 235*c8d645caSAndroid Build Coastguard Worker { 236*c8d645caSAndroid Build Coastguard Worker uint64_t value; 237*c8d645caSAndroid Build Coastguard Worker if (!pb_decode_varint(stream, &value)) 238*c8d645caSAndroid Build Coastguard Worker return false; 239*c8d645caSAndroid Build Coastguard Worker printf("%lld\n", value); 240*c8d645caSAndroid Build Coastguard Worker } 241*c8d645caSAndroid Build Coastguard Worker return true; 242*c8d645caSAndroid Build Coastguard Worker } 243*c8d645caSAndroid Build Coastguard Worker 244*c8d645caSAndroid Build Coastguard WorkerField description array 245*c8d645caSAndroid Build Coastguard Worker======================= 246*c8d645caSAndroid Build Coastguard Worker 247*c8d645caSAndroid Build Coastguard WorkerFor using the *pb_encode* and *pb_decode* functions, you need an array of pb_field_t constants describing the structure you wish to encode. This description is usually autogenerated from .proto file. 248*c8d645caSAndroid Build Coastguard Worker 249*c8d645caSAndroid Build Coastguard WorkerFor example this submessage in the Person.proto file:: 250*c8d645caSAndroid Build Coastguard Worker 251*c8d645caSAndroid Build Coastguard Worker message Person { 252*c8d645caSAndroid Build Coastguard Worker message PhoneNumber { 253*c8d645caSAndroid Build Coastguard Worker required string number = 1 [(nanopb).max_size = 40]; 254*c8d645caSAndroid Build Coastguard Worker optional PhoneType type = 2 [default = HOME]; 255*c8d645caSAndroid Build Coastguard Worker } 256*c8d645caSAndroid Build Coastguard Worker } 257*c8d645caSAndroid Build Coastguard Worker 258*c8d645caSAndroid Build Coastguard Workergenerates this field description array for the structure *Person_PhoneNumber*:: 259*c8d645caSAndroid Build Coastguard Worker 260*c8d645caSAndroid Build Coastguard Worker const pb_field_t Person_PhoneNumber_fields[3] = { 261*c8d645caSAndroid Build Coastguard Worker PB_FIELD( 1, STRING , REQUIRED, STATIC, Person_PhoneNumber, number, number, 0), 262*c8d645caSAndroid Build Coastguard Worker PB_FIELD( 2, ENUM , OPTIONAL, STATIC, Person_PhoneNumber, type, number, &Person_PhoneNumber_type_default), 263*c8d645caSAndroid Build Coastguard Worker PB_LAST_FIELD 264*c8d645caSAndroid Build Coastguard Worker }; 265*c8d645caSAndroid Build Coastguard Worker 266*c8d645caSAndroid Build Coastguard WorkerOneof 267*c8d645caSAndroid Build Coastguard Worker===== 268*c8d645caSAndroid Build Coastguard WorkerProtocol Buffers supports `oneof`_ sections. Here is an example of ``oneof`` usage:: 269*c8d645caSAndroid Build Coastguard Worker 270*c8d645caSAndroid Build Coastguard Worker message MsgType1 { 271*c8d645caSAndroid Build Coastguard Worker required int32 value = 1; 272*c8d645caSAndroid Build Coastguard Worker } 273*c8d645caSAndroid Build Coastguard Worker 274*c8d645caSAndroid Build Coastguard Worker message MsgType2 { 275*c8d645caSAndroid Build Coastguard Worker required bool value = 1; 276*c8d645caSAndroid Build Coastguard Worker } 277*c8d645caSAndroid Build Coastguard Worker 278*c8d645caSAndroid Build Coastguard Worker message MsgType3 { 279*c8d645caSAndroid Build Coastguard Worker required int32 value1 = 1; 280*c8d645caSAndroid Build Coastguard Worker required int32 value2 = 2; 281*c8d645caSAndroid Build Coastguard Worker } 282*c8d645caSAndroid Build Coastguard Worker 283*c8d645caSAndroid Build Coastguard Worker message MyMessage { 284*c8d645caSAndroid Build Coastguard Worker required uint32 uid = 1; 285*c8d645caSAndroid Build Coastguard Worker required uint32 pid = 2; 286*c8d645caSAndroid Build Coastguard Worker required uint32 utime = 3; 287*c8d645caSAndroid Build Coastguard Worker 288*c8d645caSAndroid Build Coastguard Worker oneof payload { 289*c8d645caSAndroid Build Coastguard Worker MsgType1 msg1 = 4; 290*c8d645caSAndroid Build Coastguard Worker MsgType2 msg2 = 5; 291*c8d645caSAndroid Build Coastguard Worker MsgType3 msg3 = 6; 292*c8d645caSAndroid Build Coastguard Worker } 293*c8d645caSAndroid Build Coastguard Worker } 294*c8d645caSAndroid Build Coastguard Worker 295*c8d645caSAndroid Build Coastguard WorkerNanopb will generate ``payload`` as a C union and add an additional field ``which_payload``:: 296*c8d645caSAndroid Build Coastguard Worker 297*c8d645caSAndroid Build Coastguard Worker typedef struct _MyMessage { 298*c8d645caSAndroid Build Coastguard Worker uint32_t uid; 299*c8d645caSAndroid Build Coastguard Worker uint32_t pid; 300*c8d645caSAndroid Build Coastguard Worker uint32_t utime; 301*c8d645caSAndroid Build Coastguard Worker pb_size_t which_payload; 302*c8d645caSAndroid Build Coastguard Worker union { 303*c8d645caSAndroid Build Coastguard Worker MsgType1 msg1; 304*c8d645caSAndroid Build Coastguard Worker MsgType2 msg2; 305*c8d645caSAndroid Build Coastguard Worker MsgType3 msg3; 306*c8d645caSAndroid Build Coastguard Worker } payload; 307*c8d645caSAndroid Build Coastguard Worker /* @@protoc_insertion_point(struct:MyMessage) */ 308*c8d645caSAndroid Build Coastguard Worker } MyMessage; 309*c8d645caSAndroid Build Coastguard Worker 310*c8d645caSAndroid Build Coastguard Worker``which_payload`` indicates which of the ``oneof`` fields is actually set. 311*c8d645caSAndroid Build Coastguard WorkerThe user is expected to set the filed manually using the correct field tag:: 312*c8d645caSAndroid Build Coastguard Worker 313*c8d645caSAndroid Build Coastguard Worker MyMessage msg = MyMessage_init_zero; 314*c8d645caSAndroid Build Coastguard Worker msg.payload.msg2.value = true; 315*c8d645caSAndroid Build Coastguard Worker msg.which_payload = MyMessage_msg2_tag; 316*c8d645caSAndroid Build Coastguard Worker 317*c8d645caSAndroid Build Coastguard WorkerNotice that neither ``which_payload`` field nor the unused fileds in ``payload`` 318*c8d645caSAndroid Build Coastguard Workerwill consume any space in the resulting encoded message. 319*c8d645caSAndroid Build Coastguard Worker 320*c8d645caSAndroid Build Coastguard WorkerWhen a C union is used to represent a ``oneof`` section, the union cannot have 321*c8d645caSAndroid Build Coastguard Workercallback fields or nested callback fields. Otherwise, the decoding process may 322*c8d645caSAndroid Build Coastguard Workerfail. If callbacks must be used inside a ``oneof`` section, the generator 323*c8d645caSAndroid Build Coastguard Workeroption *no_unions* should be set to *true* for that section. 324*c8d645caSAndroid Build Coastguard Worker 325*c8d645caSAndroid Build Coastguard Worker.. _`oneof`: https://developers.google.com/protocol-buffers/docs/reference/proto2-spec#oneof_and_oneof_field 326*c8d645caSAndroid Build Coastguard Worker 327*c8d645caSAndroid Build Coastguard WorkerExtension fields 328*c8d645caSAndroid Build Coastguard Worker================ 329*c8d645caSAndroid Build Coastguard WorkerProtocol Buffers supports a concept of `extension fields`_, which are 330*c8d645caSAndroid Build Coastguard Workeradditional fields to a message, but defined outside the actual message. 331*c8d645caSAndroid Build Coastguard WorkerThe definition can even be in a completely separate .proto file. 332*c8d645caSAndroid Build Coastguard Worker 333*c8d645caSAndroid Build Coastguard WorkerThe base message is declared as extensible by keyword *extensions* in 334*c8d645caSAndroid Build Coastguard Workerthe .proto file:: 335*c8d645caSAndroid Build Coastguard Worker 336*c8d645caSAndroid Build Coastguard Worker message MyMessage { 337*c8d645caSAndroid Build Coastguard Worker .. fields .. 338*c8d645caSAndroid Build Coastguard Worker extensions 100 to 199; 339*c8d645caSAndroid Build Coastguard Worker } 340*c8d645caSAndroid Build Coastguard Worker 341*c8d645caSAndroid Build Coastguard WorkerFor each extensible message, *nanopb_generator.py* declares an additional 342*c8d645caSAndroid Build Coastguard Workercallback field called *extensions*. The field and associated datatype 343*c8d645caSAndroid Build Coastguard Worker*pb_extension_t* forms a linked list of handlers. When an unknown field is 344*c8d645caSAndroid Build Coastguard Workerencountered, the decoder calls each handler in turn until either one of them 345*c8d645caSAndroid Build Coastguard Workerhandles the field, or the list is exhausted. 346*c8d645caSAndroid Build Coastguard Worker 347*c8d645caSAndroid Build Coastguard WorkerThe actual extensions are declared using the *extend* keyword in the .proto, 348*c8d645caSAndroid Build Coastguard Workerand are in the global namespace:: 349*c8d645caSAndroid Build Coastguard Worker 350*c8d645caSAndroid Build Coastguard Worker extend MyMessage { 351*c8d645caSAndroid Build Coastguard Worker optional int32 myextension = 100; 352*c8d645caSAndroid Build Coastguard Worker } 353*c8d645caSAndroid Build Coastguard Worker 354*c8d645caSAndroid Build Coastguard WorkerFor each extension, *nanopb_generator.py* creates a constant of type 355*c8d645caSAndroid Build Coastguard Worker*pb_extension_type_t*. To link together the base message and the extension, 356*c8d645caSAndroid Build Coastguard Workeryou have to: 357*c8d645caSAndroid Build Coastguard Worker 358*c8d645caSAndroid Build Coastguard Worker1. Allocate storage for your field, matching the datatype in the .proto. 359*c8d645caSAndroid Build Coastguard Worker For example, for a *int32* field, you need a *int32_t* variable to store 360*c8d645caSAndroid Build Coastguard Worker the value. 361*c8d645caSAndroid Build Coastguard Worker2. Create a *pb_extension_t* constant, with pointers to your variable and 362*c8d645caSAndroid Build Coastguard Worker to the generated *pb_extension_type_t*. 363*c8d645caSAndroid Build Coastguard Worker3. Set the *message.extensions* pointer to point to the *pb_extension_t*. 364*c8d645caSAndroid Build Coastguard Worker 365*c8d645caSAndroid Build Coastguard WorkerAn example of this is available in *tests/test_encode_extensions.c* and 366*c8d645caSAndroid Build Coastguard Worker*tests/test_decode_extensions.c*. 367*c8d645caSAndroid Build Coastguard Worker 368*c8d645caSAndroid Build Coastguard Worker.. _`extension fields`: https://developers.google.com/protocol-buffers/docs/proto#extensions 369*c8d645caSAndroid Build Coastguard Worker 370*c8d645caSAndroid Build Coastguard WorkerDefault values 371*c8d645caSAndroid Build Coastguard Worker============== 372*c8d645caSAndroid Build Coastguard WorkerProtobuf has two syntax variants, proto2 and proto3. Of these proto2 has user 373*c8d645caSAndroid Build Coastguard Workerdefinable default values that can be given in .proto file:: 374*c8d645caSAndroid Build Coastguard Worker 375*c8d645caSAndroid Build Coastguard Worker message MyMessage { 376*c8d645caSAndroid Build Coastguard Worker optional bytes foo = 1 [default = "ABC\x01\x02\x03"]; 377*c8d645caSAndroid Build Coastguard Worker optional string bar = 2 [default = "åäö"]; 378*c8d645caSAndroid Build Coastguard Worker } 379*c8d645caSAndroid Build Coastguard Worker 380*c8d645caSAndroid Build Coastguard WorkerNanopb will generate both static and runtime initialization for the default 381*c8d645caSAndroid Build Coastguard Workervalues. In `myproto.pb.h` there will be a `#define MyMessage_init_default` that 382*c8d645caSAndroid Build Coastguard Workercan be used to initialize whole message into default values:: 383*c8d645caSAndroid Build Coastguard Worker 384*c8d645caSAndroid Build Coastguard Worker MyMessage msg = MyMessage_init_default; 385*c8d645caSAndroid Build Coastguard Worker 386*c8d645caSAndroid Build Coastguard WorkerIn addition to this, `pb_decode()` will initialize message fields to defaults 387*c8d645caSAndroid Build Coastguard Workerat runtime. If this is not desired, `pb_decode_noinit()` can be used instead. 388*c8d645caSAndroid Build Coastguard Worker 389*c8d645caSAndroid Build Coastguard WorkerMessage framing 390*c8d645caSAndroid Build Coastguard Worker=============== 391*c8d645caSAndroid Build Coastguard WorkerProtocol Buffers does not specify a method of framing the messages for transmission. 392*c8d645caSAndroid Build Coastguard WorkerThis is something that must be provided by the library user, as there is no one-size-fits-all 393*c8d645caSAndroid Build Coastguard Workersolution. Typical needs for a framing format are to: 394*c8d645caSAndroid Build Coastguard Worker 395*c8d645caSAndroid Build Coastguard Worker1. Encode the message length. 396*c8d645caSAndroid Build Coastguard Worker2. Encode the message type. 397*c8d645caSAndroid Build Coastguard Worker3. Perform any synchronization and error checking that may be needed depending on application. 398*c8d645caSAndroid Build Coastguard Worker 399*c8d645caSAndroid Build Coastguard WorkerFor example UDP packets already fullfill all the requirements, and TCP streams typically only 400*c8d645caSAndroid Build Coastguard Workerneed a way to identify the message length and type. Lower level interfaces such as serial ports 401*c8d645caSAndroid Build Coastguard Workermay need a more robust frame format, such as HDLC (high-level data link control). 402*c8d645caSAndroid Build Coastguard Worker 403*c8d645caSAndroid Build Coastguard WorkerNanopb provides a few helpers to facilitate implementing framing formats: 404*c8d645caSAndroid Build Coastguard Worker 405*c8d645caSAndroid Build Coastguard Worker1. Functions *pb_encode_delimited* and *pb_decode_delimited* prefix the message data with a varint-encoded length. 406*c8d645caSAndroid Build Coastguard Worker2. Union messages and oneofs are supported in order to implement top-level container messages. 407*c8d645caSAndroid Build Coastguard Worker3. Message IDs can be specified using the *(nanopb_msgopt).msgid* option and can then be accessed from the header. 408*c8d645caSAndroid Build Coastguard Worker 409*c8d645caSAndroid Build Coastguard WorkerReturn values and error handling 410*c8d645caSAndroid Build Coastguard Worker================================ 411*c8d645caSAndroid Build Coastguard Worker 412*c8d645caSAndroid Build Coastguard WorkerMost functions in nanopb return bool: *true* means success, *false* means failure. There is also some support for error messages for debugging purposes: the error messages go in *stream->errmsg*. 413*c8d645caSAndroid Build Coastguard Worker 414*c8d645caSAndroid Build Coastguard WorkerThe error messages help in guessing what is the underlying cause of the error. The most common error conditions are: 415*c8d645caSAndroid Build Coastguard Worker 416*c8d645caSAndroid Build Coastguard Worker1) Running out of memory, i.e. stack overflow. 417*c8d645caSAndroid Build Coastguard Worker2) Invalid field descriptors (would usually mean a bug in the generator). 418*c8d645caSAndroid Build Coastguard Worker3) IO errors in your own stream callbacks. 419*c8d645caSAndroid Build Coastguard Worker4) Errors that happen in your callback functions. 420*c8d645caSAndroid Build Coastguard Worker5) Exceeding the max_size or bytes_left of a stream. 421*c8d645caSAndroid Build Coastguard Worker6) Exceeding the max_size/max_count of a string or array field 422*c8d645caSAndroid Build Coastguard Worker7) Invalid protocol buffers binary message. 423