Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Adding Encryption to Secure DFU SDK v15

I am attempting to add encryption to the secure DFU process with SDK 15.2. I am following the process described in this post, however am running into an issue related to the firmware type. 

I have made all of the changes to nrfutil as described in the original post, including regenerating the proto messages for both the python files (dfu_cc_pb.py) and the .c/.h files (dfu-cc.pb.c and dfu-cc.pb.h). I am able to generate an unencrypted package, unzip it, encrypt the app.bin file, and rezip the package for use in the dfu. After doing that, I can run 

nrfutil pkg display tmp/app_firmware-encrypted.zip

and receive the following output, suggesting that the package has been created and the new nonce value has been included:

DFU Package: <tmp/app_firmware-encrypted.zip>:
|
|- Image count: 1
|
|- Image #0:
   |- Type: application
   |- Image file: app.bin
   |- Init packet file: app.dat
      |
      |- op_code: INIT
      |- signature_type: ECDSA_P256_SHA256
      |- signature (little-endian): 991c0df5b6e175fbbd416491104d409f6148935d70af9cb3af8d1b8965e5f62e2d6e727d26e34454522530f2f4ae9aaff2a95f2c5b74d1b554d4609d892d49b2
      |
      |- fw_version: 0x00000001 (1)
      |- hw_version 0x00000034 (52)
      |- sd_req: 0xAE
      |- type: APPLICATION
      |- sd_size: 0
      |- bl_size: 0
      |- app_size: 440540
      |
      |- hash_type: SHA256
      |- hash (little-endian): 5932e4b93f5abcee9b5fc7701727067e7e598b3478063e6e235895df9e34711f
      |
      |- is_debug: False
      |- nonce (little-endian): 0df22086afa07264c4bb3c03

As you can see, this output suggests that the init packet knows I am attempting to do a DFU of "type: APPLICATION".

However when I try to actually preform the DFU with my new bootloader, I am running into an error in the function nrf_dfu_ver_validation_check(). When the function checks fw_type_ok(p_init), it is giving me an error. I've edited error logging to see what type I am getting back (see below), and somehow the init pointer has registered a type of 62, when it should in fact be 0 (corresponding to the dfu_fw_type_t enum, from dfu-cc.pb.h, also displayed below)

// nrf_dfu_ver_validation.c
nrf_dfu_result_t nrf_dfu_ver_validation_check(dfu_init_command_t const * p_init)
{
    nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
    if (!fw_type_ok(p_init))
    {
        NRF_LOG_ERROR("Invalid firmware type of %d", p_init->type); \\ telling me 62, but should be DFU_FW_TYPE_APPLICATION = 0
        ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
    }
...
}

// dfu-cc.pb.h
typedef enum
{
    DFU_FW_TYPE_APPLICATION = 0,
    DFU_FW_TYPE_SOFTDEVICE = 1,
    DFU_FW_TYPE_BOOTLOADER = 2,
    DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER = 3
} dfu_fw_type_t;

I am somewhat stumped here, I'm not sure exactly how this init packet is being loaded into memory from the zip file, and what to do to debug this issue. I've tried to add the minimum amount of code necessary to debug this, but if there is more I need to add please just request it and I will upload it. Generally I am following the linked tutorial line by line, however the line numbers of the tutorial are a bit outdated so I may have misplaced something (particularly in the nrfutil revisions). Note that I am using the code from nrfutil repository, version 4.0.0.

Parents
  • Hi, 

    I hope you will get help from on this case. Just want to let you know the m_packet (which p_command->init get the pointer from ) is generated when we decode the protobuf inside stored_init_cmd_decode(). You can step in pb_decode() to see why you get type = 62. 

    Maybe you can post your protobuf message format. 

  • I just retried this using pc-nrfutil-3.5.1 and am getting a similar error (this time it says type of 38). My protobuf message is as follows:

    package dfu;
    
    // Version 0.1
    
    // Definition of enums and types
    enum OpCode {
    	RESET	= 0;
    	INIT	= 1;
    }
    
    enum FwType {
    	APPLICATION				= 0; // default, compatible with proto3
    	SOFTDEVICE				= 1;
    	BOOTLOADER				= 2;
    	SOFTDEVICE_BOOTLOADER	= 3;
    }
    
    enum HashType {
    	NO_HASH	= 0;
    	CRC		= 1;
    	SHA128	= 2;
    	SHA256	= 3;
    	SHA512	= 4;
    }
    
    message Hash {
    	required HashType 	hash_type	= 1;
    	required bytes 		hash		= 2;
    }
    
    // Commands data
    message InitCommand {
    	optional uint32	fw_version	= 1;
    	optional uint32	hw_version	= 2;
    	repeated uint32	sd_req		= 3 [packed = true]; // packed option is default in proto3
    	optional FwType	type		= 4;
    
    	optional uint32	sd_size		= 5;
    	optional uint32	bl_size		= 6;
    	optional uint32	app_size	= 7;
    
    	optional Hash	hash		= 8;
        
      optional bool   is_debug    = 9 [default = false];
    	optional bytes  nonce		= 10;
    }
    
    message ResetCommand {
    	required uint32 timeout	= 1;
    }
    
    // Command type
    message Command {
    	optional OpCode			op_code	= 1;
    	optional InitCommand	init 	= 2;
    	optional ResetCommand	reset 	= 3;
    }
    
    // Signed command types
    enum SignatureType {
    	ECDSA_P256_SHA256	= 0;
    	ED25519				= 1;
    }
    
    message SignedCommand {
    	required Command		command			= 1;
    	required SignatureType	signature_type	= 2;
    	required bytes			signature		= 3;
    }
    
    // Parent packet type
    message Packet {
    	optional Command 		command			= 1;
    	optional SignedCommand	signed_command	= 2;
    }
    

  • One thing I can imagine might potentially be causing a problem is that when I compile the .proto into dfu_cc_pb2.py (as described in step 3 here), I am not making use of the dfu-cc.options file, however when I compile it into dfu-cc.pb.c/h, I am using nanopb_generator.py with the -f option to include dfu-cc.options i.e.

    python $NANO_PB_GEN_PATH dfu-cc.pb -f dfu-cc.options

    Could that be causing some sort of misalignment when the package is created? My dfu-cc.options file looks like:

    dfu.Hash.hash				max_size:32
    dfu.SignedCommand.signature	max_size:64
    dfu.InitCommand.sd_req		max_count:4
    dfu.InitCommand.nonce		max_size:12

  • I changed dfu-cc.options to

     

    dfu.Hash.hash				max_size:32
    dfu.SignedCommand.signature	max_size:64
    dfu.InitCommand.sd_req		max_count:12
    dfu.InitCommand.nonce		max_size:12

    since I noticed that's how @Matthew has it (sd_req max_count is 12 instead of 4), and now I'm passing the firmware type check but getting caught at the hash type check:

    "Invalid hash type of 189."

    My intuition is that there's some sort of 'alignment' issue here with parsing the message, but I'm not an expert in how proto messages work so I'm still not quite sure how I might go about debugging this.

Reply
  • I changed dfu-cc.options to

     

    dfu.Hash.hash				max_size:32
    dfu.SignedCommand.signature	max_size:64
    dfu.InitCommand.sd_req		max_count:12
    dfu.InitCommand.nonce		max_size:12

    since I noticed that's how @Matthew has it (sd_req max_count is 12 instead of 4), and now I'm passing the firmware type check but getting caught at the hash type check:

    "Invalid hash type of 189."

    My intuition is that there's some sort of 'alignment' issue here with parsing the message, but I'm not an expert in how proto messages work so I'm still not quite sure how I might go about debugging this.

Children
  • Hi, are you sure you are actually compiling with the dfu-cc.pb.c and dfu-cc.pb.h files you generated? The old dfu-cc.pb.h file in the components/libraries/bootloader/dfu folder will probably still be used if you don't rename/delete it.

    Can you post the generated files here so I can see if they look correct?

  • Hey Stian, thanks for the reply. Yes I am compiling the the dfu-cc.pb.c and dfu-cc.pb.h files. We contacted VisualGDB support and received the newest distribution, so the user-added include directories are being included before the default system directories (confirmed this is the case by checking the generated .gcc.rsp files). I dealt with the .c files by changing their "Excluded From Build" property to "Yes".

    I went back to try simply using a custom nrfutil without making any of the changes in that tutorial (just build pc-nrfutil-4.0.0 from source, generate our own dfu-cc.pb.c/h using the default dfu-cc.proto included in the SDK) and I can get everything to build and preform DFU's. This is bizarre, however, because there is a discrepancy between the SDK's dfu-cc.proto and the pc-nrfutil-4.0.0's dfu-cc.proto.

    SDK:

    package dfu;
    
    // Version 0.1
    
    enum FwType {
    	APPLICATION				= 0; // default, compatible with proto3
    	SOFTDEVICE				= 1;
    	BOOTLOADER				= 2;
    	SOFTDEVICE_BOOTLOADER	= 3;
    }
    
    enum HashType {
    	NO_HASH	= 0;
    	CRC		= 1;
    	SHA128	= 2;
    	SHA256	= 3;
    	SHA512	= 4;
    }
    
    message Hash {
    	required HashType	hash_type	= 1;
    	required bytes		hash		= 2;
    }
    
    // Commands data
    message InitCommand {
    	optional uint32	fw_version	= 1;
    	optional uint32	hw_version	= 2;
    	repeated uint32	sd_req		= 3 [packed = true]; // packed option is default in proto3
    	optional FwType	type		= 4;
    
    	optional uint32	sd_size		= 5;
    	optional uint32	bl_size		= 6;
    	optional uint32	app_size	= 7;
    
    	optional Hash	hash		= 8;
    
    	optional bool	is_debug	= 9 [default = false];
    }
    
    // Command type
    message Command {
    	enum OpCode {
    		INIT = 1;
    	}
    	optional OpCode			op_code	= 1;
    	optional InitCommand	init	= 2;
    }
    
    // Signed command types
    enum SignatureType {
    	ECDSA_P256_SHA256	= 0;
    	ED25519				= 1;
    }
    
    message SignedCommand {
    	required Command		command			= 1;
    	required SignatureType	signature_type	= 2;
    	required bytes			signature		= 3;
    }
    
    // Parent packet type
    message Packet {
    	optional Command		command			= 1;
    	optional SignedCommand	signed_command	= 2;
    }
    

    vs pc-nrfutil-4.0.0

    package dfu;
    
    // Version 0.1
    
    // Definition of enums and types
    enum OpCode {
    	RESET	= 0;
    	INIT	= 1;
    }
    
    enum FwType {
    	APPLICATION				= 0; // default, compatible with proto3
    	SOFTDEVICE				= 1;
    	BOOTLOADER				= 2;
    	SOFTDEVICE_BOOTLOADER	= 3;
    }
    
    enum HashType {
    	NO_HASH	= 0;
    	CRC		= 1;
    	SHA128	= 2;
    	SHA256	= 3;
    	SHA512	= 4;
    }
    
    message Hash {
    	required HashType 	hash_type	= 1;
    	required bytes 		hash		= 2;
    }
    
    // Commands data
    message InitCommand {
    	optional uint32	fw_version	= 1;
    	optional uint32	hw_version	= 2;
    	repeated uint32	sd_req		= 3 [packed = true]; // packed option is default in proto3
    	optional FwType	type		= 4;
    
    	optional uint32	sd_size		= 5;
    	optional uint32	bl_size		= 6;
    	optional uint32	app_size	= 7;
    
    	optional Hash	hash		= 8;
        
        optional bool   is_debug    = 9 [default = false];
    }
    
    message ResetCommand {
    	required uint32 timeout	= 1;
    }
    
    // Command type
    message Command {
    	optional OpCode			op_code	= 1;
    	optional InitCommand	init 	= 2;
    	optional ResetCommand	reset 	= 3;
    }
    
    // Signed command types
    enum SignatureType {
    	ECDSA_P256_SHA256	= 0;
    	ED25519				= 1;
    }
    
    message SignedCommand {
    	required Command		command			= 1;
    	required SignatureType	signature_type	= 2;
    	required bytes			signature		= 3;
    }
    
    // Parent packet type
    message Packet {
    	optional Command 		command			= 1;
    	optional SignedCommand	signed_command	= 2;
    }
    

    Despite this discrepancy, I can only get the DFU to work when I use the differing defaults for both. By that, I mean I need to compile (using protoc, and in the case of pb.c/h, nanopb_generator.py) the dfu-cc.pb.h/c files using the SDK version of dfu-cc.proto, and I need to compile the dfu_cc_pb2.py file in pc-nrfutil using it's default version of dfu-cc.proto. If I use either dfu-cc.proto file to compile both of them, I get an error. This makes no sense to me, since given my understanding of protobuf's it seems to me as if they should both need to be using the same dfu-cc.proto files in order to work together properly.

    Any idea how this might be possible? I'm completely stumped, don't know where to go from here...

    Here are the generated dfu-cc.pb.h/c files, these are from a branch where I attempted to use the dfu-cc.pb.proto that is distributed with pc-nrfutil-4.0.0 for both pieces, without modifications:

    dfu-cc.pb.h:

    /* Automatically generated nanopb header */
    /* Generated by nanopb-0.3.6-dev at Thu Mar 14 12:43:43 2019. */
    
    #ifndef PB_DFU_CC_PB_H_INCLUDED
    #define PB_DFU_CC_PB_H_INCLUDED
    #include <pb.h>
    
    /* @@protoc_insertion_point(includes) */
    #if PB_PROTO_HEADER_VERSION != 30
    #error Regenerate this file with the current version of nanopb generator.
    #endif
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /* Enum definitions */
    typedef enum
    {
        DFU_OP_CODE_RESET = 0,
        DFU_OP_CODE_INIT = 1
    } dfu_op_code_t;
    #define DFU_OP_CODE_MIN DFU_OP_CODE_RESET
    #define DFU_OP_CODE_MAX DFU_OP_CODE_INIT
    #define DFU_OP_CODE_ARRAYSIZE ((dfu_op_code_t)(DFU_OP_CODE_INIT+1))
    
    typedef enum
    {
        DFU_FW_TYPE_APPLICATION = 0,
        DFU_FW_TYPE_SOFTDEVICE = 1,
        DFU_FW_TYPE_BOOTLOADER = 2,
        DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER = 3
    } dfu_fw_type_t;
    #define DFU_FW_TYPE_MIN DFU_FW_TYPE_APPLICATION
    #define DFU_FW_TYPE_MAX DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER
    #define DFU_FW_TYPE_ARRAYSIZE ((dfu_fw_type_t)(DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER+1))
    
    typedef enum
    {
        DFU_HASH_TYPE_NO_HASH = 0,
        DFU_HASH_TYPE_CRC = 1,
        DFU_HASH_TYPE_SHA128 = 2,
        DFU_HASH_TYPE_SHA256 = 3,
        DFU_HASH_TYPE_SHA512 = 4
    } dfu_hash_type_t;
    #define DFU_HASH_TYPE_MIN DFU_HASH_TYPE_NO_HASH
    #define DFU_HASH_TYPE_MAX DFU_HASH_TYPE_SHA512
    #define DFU_HASH_TYPE_ARRAYSIZE ((dfu_hash_type_t)(DFU_HASH_TYPE_SHA512+1))
    
    typedef enum
    {
        DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256 = 0,
        DFU_SIGNATURE_TYPE_ED25519 = 1
    } dfu_signature_type_t;
    #define DFU_SIGNATURE_TYPE_MIN DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256
    #define DFU_SIGNATURE_TYPE_MAX DFU_SIGNATURE_TYPE_ED25519
    #define DFU_SIGNATURE_TYPE_ARRAYSIZE ((dfu_signature_type_t)(DFU_SIGNATURE_TYPE_ED25519+1))
    
    /* Struct definitions */
    typedef PB_BYTES_ARRAY_T(32) dfu_hash_hash_t;
    typedef struct {
        dfu_hash_type_t hash_type;
        dfu_hash_hash_t hash;
    /* @@protoc_insertion_point(struct:dfu_hash_t) */
    } dfu_hash_t;
    
    typedef struct {
        uint32_t timeout;
    /* @@protoc_insertion_point(struct:dfu_reset_command_t) */
    } dfu_reset_command_t;
    
    typedef struct {
        bool has_fw_version;
        uint32_t fw_version;
        bool has_hw_version;
        uint32_t hw_version;
        pb_size_t sd_req_count;
        uint32_t sd_req[4];
        bool has_type;
        dfu_fw_type_t type;
        bool has_sd_size;
        uint32_t sd_size;
        bool has_bl_size;
        uint32_t bl_size;
        bool has_app_size;
        uint32_t app_size;
        bool has_hash;
        dfu_hash_t hash;
        bool has_is_debug;
        bool is_debug;
    /* @@protoc_insertion_point(struct:dfu_init_command_t) */
    } dfu_init_command_t;
    
    typedef struct {
        bool has_op_code;
        dfu_op_code_t op_code;
        bool has_init;
        dfu_init_command_t init;
        bool has_reset;
        dfu_reset_command_t reset;
    /* @@protoc_insertion_point(struct:dfu_command_t) */
    } dfu_command_t;
    
    typedef PB_BYTES_ARRAY_T(64) dfu_signed_command_signature_t;
    typedef struct {
        dfu_command_t command;
        dfu_signature_type_t signature_type;
        dfu_signed_command_signature_t signature;
    /* @@protoc_insertion_point(struct:dfu_signed_command_t) */
    } dfu_signed_command_t;
    
    typedef struct {
        bool has_command;
        dfu_command_t command;
        bool has_signed_command;
        dfu_signed_command_t signed_command;
    /* @@protoc_insertion_point(struct:dfu_packet_t) */
    } dfu_packet_t;
    
    /* Default values for struct fields */
    extern const bool dfu_init_command_is_debug_default;
    
    /* Initializer values for message structs */
    #define DFU_HASH_INIT_DEFAULT                    {(dfu_hash_type_t)0, {0, {0}}}
    #define DFU_INIT_COMMAND_INIT_DEFAULT            {false, 0, false, 0, 0, {0, 0, 0, 0}, false, (dfu_fw_type_t)0, false, 0, false, 0, false, 0, false, DFU_HASH_INIT_DEFAULT, false, false}
    #define DFU_RESET_COMMAND_INIT_DEFAULT           {0}
    #define DFU_COMMAND_INIT_DEFAULT                 {false, (dfu_op_code_t)0, false, DFU_INIT_COMMAND_INIT_DEFAULT, false, DFU_RESET_COMMAND_INIT_DEFAULT}
    #define DFU_SIGNED_COMMAND_INIT_DEFAULT          {DFU_COMMAND_INIT_DEFAULT, (dfu_signature_type_t)0, {0, {0}}}
    #define DFU_PACKET_INIT_DEFAULT                  {false, DFU_COMMAND_INIT_DEFAULT, false, DFU_SIGNED_COMMAND_INIT_DEFAULT}
    #define DFU_HASH_INIT_ZERO                       {(dfu_hash_type_t)0, {0, {0}}}
    #define DFU_INIT_COMMAND_INIT_ZERO               {false, 0, false, 0, 0, {0, 0, 0, 0}, false, (dfu_fw_type_t)0, false, 0, false, 0, false, 0, false, DFU_HASH_INIT_ZERO, false, 0}
    #define DFU_RESET_COMMAND_INIT_ZERO              {0}
    #define DFU_COMMAND_INIT_ZERO                    {false, (dfu_op_code_t)0, false, DFU_INIT_COMMAND_INIT_ZERO, false, DFU_RESET_COMMAND_INIT_ZERO}
    #define DFU_SIGNED_COMMAND_INIT_ZERO             {DFU_COMMAND_INIT_ZERO, (dfu_signature_type_t)0, {0, {0}}}
    #define DFU_PACKET_INIT_ZERO                     {false, DFU_COMMAND_INIT_ZERO, false, DFU_SIGNED_COMMAND_INIT_ZERO}
    
    /* Field tags (for use in manual encoding/decoding) */
    #define DFU_HASH_HASH_TYPE_TAG                   1
    #define DFU_HASH_HASH_TAG                        2
    #define DFU_RESET_COMMAND_TIMEOUT_TAG            1
    #define DFU_INIT_COMMAND_FW_VERSION_TAG          1
    #define DFU_INIT_COMMAND_HW_VERSION_TAG          2
    #define DFU_INIT_COMMAND_SD_REQ_TAG              3
    #define DFU_INIT_COMMAND_TYPE_TAG                4
    #define DFU_INIT_COMMAND_SD_SIZE_TAG             5
    #define DFU_INIT_COMMAND_BL_SIZE_TAG             6
    #define DFU_INIT_COMMAND_APP_SIZE_TAG            7
    #define DFU_INIT_COMMAND_HASH_TAG                8
    #define DFU_INIT_COMMAND_IS_DEBUG_TAG            9
    #define DFU_COMMAND_OP_CODE_TAG                  1
    #define DFU_COMMAND_INIT_TAG                     2
    #define DFU_COMMAND_RESET_TAG                    3
    #define DFU_SIGNED_COMMAND_COMMAND_TAG           1
    #define DFU_SIGNED_COMMAND_SIGNATURE_TYPE_TAG    2
    #define DFU_SIGNED_COMMAND_SIGNATURE_TAG         3
    #define DFU_PACKET_COMMAND_TAG                   1
    #define DFU_PACKET_SIGNED_COMMAND_TAG            2
    
    /* Struct field encoding specification for nanopb */
    extern const pb_field_t dfu_hash_fields[3];
    extern const pb_field_t dfu_init_command_fields[10];
    extern const pb_field_t dfu_reset_command_fields[2];
    extern const pb_field_t dfu_command_fields[4];
    extern const pb_field_t dfu_signed_command_fields[4];
    extern const pb_field_t dfu_packet_fields[3];
    
    /* Maximum encoded size of messages (where known) */
    #define DFU_HASH_SIZE                            36
    #define DFU_INIT_COMMAND_SIZE                    96
    #define DFU_RESET_COMMAND_SIZE                   6
    #define DFU_COMMAND_SIZE                         108
    #define DFU_SIGNED_COMMAND_SIZE                  178
    #define DFU_PACKET_SIZE                          291
    
    /* Message IDs (where set with "msgid" option) */
    #ifdef PB_MSGID
    
    #define DFU_CC_MESSAGES \
    
    
    #endif
    
    #ifdef __cplusplus
    } /* extern "C" */
    #endif
    /* @@protoc_insertion_point(eof) */
    
    #endif
    

    dfu-cc.pb.c:

    /* Automatically generated nanopb constant definitions */
    /* Generated by nanopb-0.3.6-dev at Thu Mar 14 12:43:43 2019. */
    
    #include "dfu-cc.pb.h"
    
    /* @@protoc_insertion_point(includes) */
    #if PB_PROTO_HEADER_VERSION != 30
    #error Regenerate this file with the current version of nanopb generator.
    #endif
    
    const bool dfu_init_command_is_debug_default = false;
    
    
    const pb_field_t dfu_hash_fields[3] = {
        PB_FIELD(  1, UENUM   , REQUIRED, STATIC  , FIRST, dfu_hash_t, hash_type, hash_type, 0),
        PB_FIELD(  2, BYTES   , REQUIRED, STATIC  , OTHER, dfu_hash_t, hash, hash_type, 0),
        PB_LAST_FIELD
    };
    
    const pb_field_t dfu_init_command_fields[10] = {
        PB_FIELD(  1, UINT32  , OPTIONAL, STATIC  , FIRST, dfu_init_command_t, fw_version, fw_version, 0),
        PB_FIELD(  2, UINT32  , OPTIONAL, STATIC  , OTHER, dfu_init_command_t, hw_version, fw_version, 0),
        PB_FIELD(  3, UINT32  , REPEATED, STATIC  , OTHER, dfu_init_command_t, sd_req, hw_version, 0),
        PB_FIELD(  4, UENUM   , OPTIONAL, STATIC  , OTHER, dfu_init_command_t, type, sd_req, 0),
        PB_FIELD(  5, UINT32  , OPTIONAL, STATIC  , OTHER, dfu_init_command_t, sd_size, type, 0),
        PB_FIELD(  6, UINT32  , OPTIONAL, STATIC  , OTHER, dfu_init_command_t, bl_size, sd_size, 0),
        PB_FIELD(  7, UINT32  , OPTIONAL, STATIC  , OTHER, dfu_init_command_t, app_size, bl_size, 0),
        PB_FIELD(  8, MESSAGE , OPTIONAL, STATIC  , OTHER, dfu_init_command_t, hash, app_size, &dfu_hash_fields),
        PB_FIELD(  9, BOOL    , OPTIONAL, STATIC  , OTHER, dfu_init_command_t, is_debug, hash, &dfu_init_command_is_debug_default),
        PB_LAST_FIELD
    };
    
    const pb_field_t dfu_reset_command_fields[2] = {
        PB_FIELD(  1, UINT32  , REQUIRED, STATIC  , FIRST, dfu_reset_command_t, timeout, timeout, 0),
        PB_LAST_FIELD
    };
    
    const pb_field_t dfu_command_fields[4] = {
        PB_FIELD(  1, UENUM   , OPTIONAL, STATIC  , FIRST, dfu_command_t, op_code, op_code, 0),
        PB_FIELD(  2, MESSAGE , OPTIONAL, STATIC  , OTHER, dfu_command_t, init, op_code, &dfu_init_command_fields),
        PB_FIELD(  3, MESSAGE , OPTIONAL, STATIC  , OTHER, dfu_command_t, reset, init, &dfu_reset_command_fields),
        PB_LAST_FIELD
    };
    
    const pb_field_t dfu_signed_command_fields[4] = {
        PB_FIELD(  1, MESSAGE , REQUIRED, STATIC  , FIRST, dfu_signed_command_t, command, command, &dfu_command_fields),
        PB_FIELD(  2, UENUM   , REQUIRED, STATIC  , OTHER, dfu_signed_command_t, signature_type, command, 0),
        PB_FIELD(  3, BYTES   , REQUIRED, STATIC  , OTHER, dfu_signed_command_t, signature, signature_type, 0),
        PB_LAST_FIELD
    };
    
    const pb_field_t dfu_packet_fields[3] = {
        PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, dfu_packet_t, command, command, &dfu_command_fields),
        PB_FIELD(  2, MESSAGE , OPTIONAL, STATIC  , OTHER, dfu_packet_t, signed_command, command, &dfu_signed_command_fields),
        PB_LAST_FIELD
    };
    
    
    /* Check that field information fits in pb_field_t */
    #if !defined(PB_FIELD_32BIT)
    /* If you get an error here, it means that you need to define PB_FIELD_32BIT
     * compile-time option. You can do that in pb.h or on compiler command line.
     * 
     * The reason you need to do this is that some of your messages contain tag
     * numbers or field sizes that are larger than what can fit in 8 or 16 bit
     * field descriptors.
     */
    PB_STATIC_ASSERT((pb_membersize(dfu_init_command_t, hash) < 65536 && pb_membersize(dfu_command_t, init) < 65536 && pb_membersize(dfu_command_t, reset) < 65536 && pb_membersize(dfu_signed_command_t, command) < 65536 && pb_membersize(dfu_packet_t, command) < 65536 && pb_membersize(dfu_packet_t, signed_command) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_dfu_hash_dfu_init_command_dfu_reset_command_dfu_command_dfu_signed_command_dfu_packet)
    #endif
    
    #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
    /* If you get an error here, it means that you need to define PB_FIELD_16BIT
     * compile-time option. You can do that in pb.h or on compiler command line.
     * 
     * The reason you need to do this is that some of your messages contain tag
     * numbers or field sizes that are larger than what can fit in the default
     * 8 bit descriptors.
     */
    PB_STATIC_ASSERT((pb_membersize(dfu_init_command_t, hash) < 256 && pb_membersize(dfu_command_t, init) < 256 && pb_membersize(dfu_command_t, reset) < 256 && pb_membersize(dfu_signed_command_t, command) < 256 && pb_membersize(dfu_packet_t, command) < 256 && pb_membersize(dfu_packet_t, signed_command) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_dfu_hash_dfu_init_command_dfu_reset_command_dfu_command_dfu_signed_command_dfu_packet)
    #endif
    
    
    /* @@protoc_insertion_point(eof) */
    

Related