[security] Introducing signing support to MySensors


  • Contest Winner

    Thanks @duovis,
    Yes, I welcome anyone who has the HW to provide a IO routine for I2C-variants of ATSHA204A. I don't have the hw myself though.



  • @Anticimex Ok, I'll try to play with it and see if I can come up with something that works on I2C.


  • Contest Winner

    @duovis Great. I'll happily review any code. You should only need to worry about the low level stuff.


  • Hardware Contributor

    Hello all!

    Two fast question! Can I have nodes working with ATSHA204A chip and others with software?

    And, can I have nodes with signing on and others off? Or if I add signing to my network, all nodes must have it?

    Thank you all!


  • Contest Winner

    @Soloam
    You can mix nodes with soft signing and ATSHA signing as you like.
    You can mix nodes with signing on and off as well. The GW will only sign messages to nodes that require it, and it will also only check signatures from nodes that require signatures. So you can have one node which support/require signing and another which don't. The GW will be able to exchange messages with both nodes.


  • Hardware Contributor

    Great work indeed!

    Thank you @Anticimex


  • Contest Winner

    @Soloam thanks 🙂



  • Slightly silly question, but did anyone manage to get signing working (MySigningAtsha204Soft signer;) on Arduino Uno on MS 1.5.4 on the Ethernet gateway please? I am going out of memory and really hate to upgrade it to Mega


  • Contest Winner

    @alexsh1 if you feel adventurous try 2.0.0-beta2, or if you are patient, go to 2.0.0 in a few months and redesigns will have made space available for you.



  • @Anticimex Thanks - I am currently trying an Ethernet GW and a node (Sensebender Micro) with dev branch. I am stuck at personalisation. I cannot lock data. Any idea what I am doing wrong?

    This is Sensebender (with ATSHA204):

    Personalization sketch for MySensors usage.
    -------------------------------------------
    Device revision: 00020009
    Device serial:   {0x01,0x23,0x53,0x3F,0x52,0x6A,0x1A,0x06,0xEE}
    0123533F526A1A06EE
    Skipping configuration write and lock (configuration already locked).
    Chip configuration:
    EEPROM DATA:
    SOFT_HMAC_KEY | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    SOFT_SERIAL   | FFFFFFFFFFFFFFFFFF
    AES_KEY       | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    ATSHA204A DATA:
               SN[0:1]           |         SN[2:3]           | 01   23 | 53   3F   
                              Revnum                         | 00   09   04   00   
                              SN[4:7]                        | 52   6A   1A   06   
        SN[8]    |  Reserved13   | I2CEnable | Reserved15    | EE | 13 | 00 | 00   
      I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | C8 | 00 | 55 | 00   
             SlotConfig00        |       SlotConfig01        | 8F   80 | 80   A1   
             SlotConfig02        |       SlotConfig03        | 82   E0 | A3   60   
             SlotConfig04        |       SlotConfig05        | 94   40 | A0   85   
             SlotConfig06        |       SlotConfig07        | 86   40 | 87   07   
             SlotConfig08        |       SlotConfig09        | 0F   00 | 89   F2   
             SlotConfig0A        |       SlotConfig0B        | 8A   7A | 0B   8B   
             SlotConfig0C        |       SlotConfig0D        | 0C   4C | DD   4D   
             SlotConfig0E        |       SlotConfig0F        | C2   42 | AF   8F   
      UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | FF | 00 | FF | 00   
      UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | FF | 00 | FF | 00   
      UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | FF | 00 | FF | 00   
      UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | FF | 00 | FF | 00   
                          LastKeyUse[0:3]                    | FF   FF   FF   FF   
                          LastKeyUse[4:7]                    | FF   FF   FF   FF   
                          LastKeyUse[8:B]                    | FF   FF   FF   FF   
                          LastKeyUse[C:F]                    | FF   FF   FF   FF   
      UserExtra  |    Selector   | LockValue |  LockConfig   | 00 | 00 | 55 | 00   
    Take note of this key, it will never be the shown again:
    #define MY_HMAC_KEY [deleted]
    Writing key to slot 0...
    Send SPACE character to lock data...
    Data lock failed. Response: D3
    Halting!
    

  • Contest Winner

    @alexsh1 actually, I have never actually locked data. Could be a bug there. But I also highly recommend that you don't. If you do, you will never be able to change hmac key in that device.



  • @Anticimex So this is no problem if the key is not locked? I was just following the manual

    On a separate note, I cannot get soft_serial written into the EEPROM:

    #define LOCK_CONFIGURATION
    //#define LOCK_DATA
    //#define SKIP_KEY_STORAGE
    //#define USER_KEY
    //#define SKIP_UART_CONFIRMATION
    #define USE_SOFT_SIGNING
    #define STORE_SOFT_KEY
    #define USER_SOFT_KEY
    #define STORE_SOFT_SERIAL
    #define USER_SOFT_SERIAL
    #define STORE_AES_KEY
    #define USER_AES_KEY```
    

    I have defined the key under #define MY_SOFT_SERIAL [key]

    Personalization sketch for MySensors usage.
    -------------------------------------------
    This value will be stored in EEPROM as soft HMAC key:
    #define MY_SOFT_HMAC_KEY [deleted]
    Using this user supplied AES key:
    #define MY_AES_KEY [deleted]
    EEPROM configuration:
    SOFT_HMAC_KEY | [deleted]
    SOFT_SERIAL   | FFFFFFFFFFFFFFFFFF
    AES_KEY       | [deleted]
    --------------------------------
    Personalization is now complete.
    

  • Contest Winner

    @alexsh1 Hopefully the manual informs about the risks with locking data (that you cannot change the key afterwards). Atmel is somewhat vague on the security implications; they say that you can not read the key anyway but it is "more secure" to lock data. But personally, I have not found a way to read it, and I prefer to be able to change my HMAC key in my devices if it should be compromised.

    Strange that you don't get the soft serial. I see nothing obviously wrong with your config. But I do see that you probably sensored your uart log a bit too hard because there are other lines missing there.
    You should have seen this

    Using this user supplied soft HMAC key:
    #define MY_SOFT_HMAC_KEY [deleted]
    

    if you have enabled this:

    #define STORE_SOFT_KEY
    #define USER_SOFT_KEY
    

    You are sure you have no #undef or some accidental comment or similar. As you see in the personalizer code, it is not that complicated. If the flags are enabled, you should at least get some printouts. But since (if your UART dump is correct) you get nothing, I suspect the flags are not really "on".



  • @Anticimex said:

    Strange that you don't get the soft serial. I see nothing obviously wrong with your config. But I do see that you probably sensored your uart log a bit too hard because there are other lines missing there.
    You should have seen this

    Using this user supplied soft HMAC key:
    #define MY_SOFT_HMAC_KEY [deleted]
    

    if you have enabled this:

    #define STORE_SOFT_KEY
    #define USER_SOFT_KEY
    

    You are sure you have no #undef or some accidental comment or similar. As you see in the personalizer code, it is not that complicated. If the flags are enabled, you should at least get some printouts. But since (if your UART dump is correct) you get nothing, I suspect the flags are not really "on".

    OK, it was Arduino glitch - any changes in the sketch were not reflected on the compilation. Rebooted my PC and restarted Arduino and all works as expected.

    A few questions: Mixing ATSHA204 and soft signing - Does HMAC key (one stored in ATSHA204 of say a node and another one in GW's EEPROM) have to be the same? Also I understand one can store HMAC key on both ATSHA204 and EEPROM of one device (say, Sensebender)? I understand that SOFT_KEY has to be unique for every device?


  • Contest Winner

    @alexsh1 Ok, well Arduino IDE sucks totally.

    You can mix ATSHA204A and soft signing as much as you like. But for any two nodes to exchange signed data the HMAC keys have to be identical.
    Yes, you can store a HMAC key in both ATSHA204A and EEPROM. These can be different if you like (and I recommend they are as the EEPROM can be dumped if the node falls into the wrong hands).
    However, if you want that node to communicate signed data to another node, that node must use a matching HMAC key.
    SOFT_KEY is the HMAC key stored in EEPROM, it must not be unique for every device. If it is, no device will be able to sign data to any other node and expect that node to accept that data.
    SOFT_SERIAL on the other hand, must be unique to serve any useful purpose for whitelisting. If you use the ATSHA204A, the serial fused in the device will be used and that cannot be changed, and is according to Atmel, unique.



  • @Anticimex Ok, but is there a reason why one would have HMAC key in both ATSHA204a and EEPROM?


  • Contest Winner

    @alexsh1 no, not really. If you have a atsha204a the only reason to not use it would be performance. Software signing executes slightly faster due to the single write protocol of the atsha.



  • @Anticimex Thanks very much for your help - I must admit it was a bit of a challenge to jump straight away from a stable 1.5.4 to 2.0 beta


  • Contest Winner

    @alexsh1 yes there have been a lot of changes but hopefully they are perceived as improvements. Feedback on signing usability is always welcome 🙂



  • @Anticimex BTW, is signing compatible between 1.5.4 and 2.0b?


  • Contest Winner

    @alexsh1 no, it is not



  • @Anticimex Right, this is why I am not able to sign 1.5.4 nodes with 2.0b GW.
    In fact when I inserted #define MY_SIGNING_REQUEST_SIGNATURES into the GW code, some nodes stopped working and I think it has to be with signing as GW is throwing a lot of messages that signing failed.

    Bottom line is that I need to upgrade pretty much all sensors 😞


  • Contest Winner

    @alexsh1 yes, Unfortunately. But it is a huge release upcoming. And a major version step, hence the incompatibilities. Hopefully, the changes made will make it easier to do future maintenance.



  • Hi. Is there any difference in using RFM69? Signing is supported using that radio? Thanks


  • Contest Winner

    @cingolanifede signing has nothing to to with which radio you choose so yes. It supports any transport, but to my knowledge it has only been actually tested with nrf24 and rfm69.



  • @Anticimex I must admit that signing is working really-really nicely on my custom made nodes (Soft sign and ATSHA204A)

    Apart from a small issue with the sensebender, which I believe is not a signing issue, it is working like a charm. All credit to you! Thank you

    Starting sensor (RNNNAS, 2.0.0-beta)
    Radio init successful.
    HTU21D Sensor1.1 - Online!
    isMetric: 1
    TempDiff :1098.00
    HumDiff  :136.75
    T: 998.00
    H: 36.75
    send: 5-5-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:998.0
    send: 5-5-0-0 s=1,c=1,t=1,pt=7,l=5,sg=0,st=ok:36.7
    send: 5-5-0-0 s=2,c=1,t=38,pt=7,l=5,sg=0,st=ok:3.29
    send: 5-5-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:106
    Signing required
    send: 5-5-0-0 s=255,c=3,t=15,pt=0,l=2,sg=0,st=ok:
    Waiting for GW to send signing preferences...
    Skipping security for command 3 type 15
    read: 0-0-5 s=255,c=3,t=15,pt=0,l=2,sg=0:
    Mark node 0 as one that do not require signed messages
    Mark node 0 as one that do not require whitelisting
    send: 5-5-0-0 s=255,c=0,t=17,pt=0,l=10,sg=0,st=ok:2.0.0-beta
    send: 5-5-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
    Skipping security for command 3 type 16
    read: 0-0-5 s=255,c=3,t=16,pt=0,l=0,sg=0:
    Signing backend: ATSHA204Soft
    SHA256: 2C4A871ACCAE26760F41E547DD39B7B816FE22EEBCD8DFA2FE00000000000000
    Transmittng nonce
    send: 5-5-0-0 s=255,c=3,t=17,pt=6,l=25,sg=0,st=ok:2C4A871ACCAE26760F41E547DD39B7B816FE22EEBCD8DFA2FE
    Signature in message: 01C31110DAE29D5DCD3771F68B6F29B5CCCF43A3D5397CC8
    Message to process: 00050E0306FF4D
    Current nonce: 2C4A871ACCAE26760F41E547DD39B7B816FE22EEBCD8DFA2FEAAAAAAAAAAAAAA
    HMAC: 0CC31110DAE29D5DCD3771F68B6F29B5CCCF43A3D5397CC89A82A89D87E931B8
    Signature OK
    read: 0-0-5 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    send: 5-5-0-0 s=255,c=3,t=11,pt=0,l=24,sg=0,st=ok:Temp/Hum Sensor - HTU21D
    send: 5-5-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:1.1
    send: 5-5-0-0 s=0,c=0,t=6,pt=0,l=0,sg=0,st=ok:
    send: 5-5-0-0 s=1,c=0,t=7,pt=0,l=0,sg=0,st=ok:
    send: 5-5-0-0 s=2,c=0,t=13,pt=0,l=0,sg=0,st=ok:
    Init complete, id=5, parent=0, distance=1
    TempDiff :971.94
    HumDiff  :0.02
    T: 26.06
    H: 36.72
    send: 5-5-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:26.1
    send: 5-5-0-0 s=1,c=1,t=1,pt=7,l=5,sg=0,st=ok:36.7
    

  • Contest Winner

    @alexsh1 I'm really glad to hear that. Thank you! Glad that signing is being used and is perceived as something not to complicated to bother with. It sets us apart from many other projects dealing with the same thing 🙂



  • @Anticimex I did not say it was not complicated 🙂
    Just kidding - speaking just for myself, it did require some time investment to understand the concept and then upgrading my gateway and my nodes (I am still in the process of rolling signing across the rest of my nodes) to MySensors 2.0b. I probably spent more time upgrading MySensors lib and breaking some hardware in the meantime (the SMA connector on the nrf24l01+ PA+LNA) than the actual signing.


  • Contest Winner

    @alexsh1 yeah, well if there is room for improvement in the documentation then feel free to help put with suggestions if there is anything unclear about that 🙂 I use doxygen to document signing features, and a link is available on the GitHub "front-page" (the readme.md)



  • @Anticimex I think a noob's section would be good. Having said that, the point is that signing is not something beginners should touch. What do you think?

    How about a section on the web-site? Somewhere here - https://www.mysensors.org/build/


  • Contest Winner

    @alexsh1 hm, yeah, perhaps something for @hek to consider. At least a link to the signing section of the doxygen docs could be placed there. I have tried to make the documentation as step-by-step friendly as I can. That said, as I also did the actual implementation, I may well be blind for certain aspects I take for granted that a "novice" does not.


  • Admin

    The next release of the main site will be much more flexible and integrated with openhardware-added projects. The idea is to allow community members to maintain their projects and/or "articles" themselves. The how-to for signing is a good example of an article.



  • This tutorial is up to date for 2.0 release ?


  • Contest Winner

    @Fabien Yes, top post is now updated for 2.0.0. Documentation is in doxygen.



  • Thank you @Anticimex I will update my network soon and had RFM69 Encryption too.



  • Trying this:
    https://www.mysensors.org/build/raspberry

    How do I enable signing and give the gateway the serial, hmac and aes-key when running on Linux? (rPi).

    Edit: Pin 7 as random number generator maybe need some change?


  • Contest Winner

    @NiklasO @marceloaqno is working on this.



  • Hi,
    I have about 100 ATSHA204 I2C variant to be used in a MySensors project.
    Do you think that by modifying the personalizer sketch to disable the I2C bit in the configuration (0x03 word address) the chips can be set to be used as single-wire, or are they hardcoded to use only one protocol, but then why having the config bit?


  • Contest Winner

    @executivul The bit is readonly. You cannot change it. It is used to determine the variant of chip, not to select mode of operation.
    From the documentation:
    0_1478094689558_upload-93242040-4814-4ad6-8951-4ad4d1e99a23
    But you are welcome to submit a pull request for adding support for I2C variants of ATSHA204a. I have none myself so I have not bothered looking into that and currently I am out of time to spend on it I am afraid.



  • @Anticimex said:
    But you are welcome to submit a pull request for adding support for I2C variants of ATSHA204a. I have none myself so I have not bothered looking into that and currently I am out of time to spend on it I am afraid.

    Please excuse my noobish ignorance: How and where do I submit one?


  • Contest Winner

    @executivul By forking the MySensors core repository and create a local git branch, do your code, push it back to your fork on GitHub and then create a pull request from that. There are good guides on GitHub for how do do it.



  • ok, thank you, but do you know why the sketch didnt generate the keys, and instead of random i get only keys ffffffffffff ?
    thank you


  • Contest Winner

    @meddie Without actually seeing your sketch it is pretty hard for me to help with anything 😉
    My guess is, you did not enable the proper defines to instruct it to generate and store any keys.



  • @Anticimex
    Hi i have posted my sketch few posts ago, but no problem here is it:

    
    
    #include "sha204_library.h"
    #include "sha204_lib_return_codes.h"
    #define MY_CORE_ONLY
    #include <MySensors.h>
    
    #if DOXYGEN
    #define LOCK_CONFIGURATION
    #define LOCK_DATA
    #define SKIP_KEY_STORAGE
    #define USER_KEY
    #define SKIP_UART_CONFIRMATION
    #define USE_SOFT_SIGNING
    #define STORE_SOFT_KEY
    #define USER_SOFT_KEY
    #define STORE_SOFT_SERIAL
    #define USER_SOFT_SERIAL
    #define STORE_AES_KEY
    #define USER_AES_KEY
    #endif
    
    //#define LOCK_CONFIGURATION
    
    //#define LOCK_DATA
    
    #define SKIP_KEY_STORAGE
    
    //#define USER_KEY
    
    //#define SKIP_UART_CONFIRMATION
    
    //#define USE_SOFT_SIGNING
    
    //#define STORE_SOFT_KEY
    
    //#define USER_SOFT_KEY
    
    //#define STORE_SOFT_SERIAL
    
    //#define USER_SOFT_SERIAL
    
    //#define STORE_AES_KEY
    
    //#define USER_AES_KEY
    
    #if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY)
    #error You have to define USER_KEY for boards that does not have UART
    #endif
    
    #ifdef USER_KEY
    /** @brief The user-defined HMAC key to use for personalization */
    #define MY_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    /** @brief The data to store in key slot 0 */
    const uint8_t user_key_data[32] = {MY_HMAC_KEY};
    #endif
    
    #ifdef USER_SOFT_KEY
    /** @brief The user-defined soft HMAC key to use for EEPROM personalization */
    #define MY_SOFT_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    /** @brief The data to store as soft HMAC key in EEPROM */
    const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY};
    #endif
    
    #ifdef USER_SOFT_SERIAL
    /** @brief The user-defined soft serial to use for EEPROM personalization */
    #define MY_SOFT_SERIAL 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    /** @brief The data to store as soft serial in EEPROM */
    const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
    #endif
    
    #ifdef USER_AES_KEY
    /** @brief The user-defined AES key to use for EEPROM personalization */
    #define MY_AES_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    /** @brief The data to store as AES key in EEPROM */
    const uint8_t user_aes_key[16] = {MY_AES_KEY};
    #endif
    
    #ifndef USE_SOFT_SIGNING
    const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A
    atsha204Class sha204(sha204Pin);
    #endif
    
    /** @brief Print a error notice and halt the execution */
    void halt()
    {
    	Serial.println(F("Halting!"));
    	while(1);
    }
    
    #ifndef USE_SOFT_SIGNING
    
    uint16_t write_config_and_get_crc()
    {
    	uint16_t crc = 0;
    	uint8_t config_word[4];
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    	bool do_write;
    
    	for (int i=0; i < 88; i += 4) {
    		do_write = true;
    		if (i == 20) {
    			config_word[0] = 0x8F;
    			config_word[1] = 0x80;
    			config_word[2] = 0x80;
    			config_word[3] = 0xA1;
    		} else if (i == 24) {
    			config_word[0] = 0x82;
    			config_word[1] = 0xE0;
    			config_word[2] = 0xA3;
    			config_word[3] = 0x60;
    		} else if (i == 28) {
    			config_word[0] = 0x94;
    			config_word[1] = 0x40;
    			config_word[2] = 0xA0;
    			config_word[3] = 0x85;
    		} else if (i == 32) {
    			config_word[0] = 0x86;
    			config_word[1] = 0x40;
    			config_word[2] = 0x87;
    			config_word[3] = 0x07;
    		} else if (i == 36) {
    			config_word[0] = 0x0F;
    			config_word[1] = 0x00;
    			config_word[2] = 0x89;
    			config_word[3] = 0xF2;
    		} else if (i == 40) {
    			config_word[0] = 0x8A;
    			config_word[1] = 0x7A;
    			config_word[2] = 0x0B;
    			config_word[3] = 0x8B;
    		} else if (i == 44) {
    			config_word[0] = 0x0C;
    			config_word[1] = 0x4C;
    			config_word[2] = 0xDD;
    			config_word[3] = 0x4D;
    		} else if (i == 48) {
    			config_word[0] = 0xC2;
    			config_word[1] = 0x42;
    			config_word[2] = 0xAF;
    			config_word[3] = 0x8F;
    		} else if (i == 52 || i == 56 || i == 60 || i == 64) {
    			config_word[0] = 0xFF;
    			config_word[1] = 0x00;
    			config_word[2] = 0xFF;
    			config_word[3] = 0x00;
    		} else if (i == 68 || i == 72 || i == 76 || i == 80) {
    			config_word[0] = 0xFF;
    			config_word[1] = 0xFF;
    			config_word[2] = 0xFF;
    			config_word[3] = 0xFF;
    		} else {
    			// All other configs are untouched
    			ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Failed to read config. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    			// Set config_word to the read data
    			config_word[0] = rx_buffer[SHA204_BUFFER_POS_DATA+0];
    			config_word[1] = rx_buffer[SHA204_BUFFER_POS_DATA+1];
    			config_word[2] = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    			config_word[3] = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    			do_write = false;
    		}
    
    		// Update crc with CRC for the current word
    		crc = sha204.calculateAndUpdateCrc(4, config_word, crc);
    
    		// Write config word
    		if (do_write) {
    			ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_CONFIG,
    			                                  i >> 2, 4, config_word, 0, NULL, 0, NULL,
    			                                  WRITE_COUNT_SHORT, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Failed to write config word at address "));
    				Serial.print(i);
    				Serial.print(F(". Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    		}
    	}
    	return crc;
    }
    
    /**
     * @brief Write provided key to slot 0
     * @param key The key data to write
     */
    void write_key(uint8_t* key)
    {
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    
    	// Write key to slot 0
    	ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG,
    	                                  0, SHA204_ZONE_ACCESS_32, key, 0, NULL, 0, NULL,
    	                                  WRITE_COUNT_LONG, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to write key to slot 0. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	}
    }
    #endif // not USE_SOFT_SIGNING
    
    /** @brief Dump current configuration to UART */
    void dump_configuration()
    {
    	uint8_t buffer[32];
    #ifndef USE_SOFT_SIGNING
    	Serial.println(F("EEPROM DATA:"));
    #endif
    	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
    	Serial.print(F("SOFT_HMAC_KEY | "));
    	for (int j=0; j<32; j++) {
    		if (buffer[j] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(buffer[j], HEX);
    	}
    	Serial.println();
    	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
    	Serial.print(F("SOFT_SERIAL   | "));
    	for (int j=0; j<9; j++) {
    		if (buffer[j] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(buffer[j], HEX);
    	}
    	Serial.println();
    	hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
    	Serial.print(F("AES_KEY       | "));
    	for (int j=0; j<16; j++) {
    		if (buffer[j] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(buffer[j], HEX);
    	}
    	Serial.println();
    #ifndef USE_SOFT_SIGNING
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    	Serial.println(F("ATSHA204A DATA:"));
    	for (int i=0; i < 88; i += 4) {
    		ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
    		if (ret_code != SHA204_SUCCESS) {
    			Serial.print(F("Failed to read config. Response: "));
    			Serial.println(ret_code, HEX);
    			halt();
    		}
    		if (i == 0x00) {
    			Serial.print(F("           SN[0:1]           |         SN[2:3]           | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x04) {
    			Serial.print(F("                          Revnum                         | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x08) {
    			Serial.print(F("                          SN[4:7]                        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x0C) {
    			Serial.print(F("    SN[8]    |  Reserved13   | I2CEnable | Reserved15    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x10) {
    			Serial.print(F("  I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x14) {
    			Serial.print(F("         SlotConfig00        |       SlotConfig01        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x18) {
    			Serial.print(F("         SlotConfig02        |       SlotConfig03        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x1C) {
    			Serial.print(F("         SlotConfig04        |       SlotConfig05        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x20) {
    			Serial.print(F("         SlotConfig06        |       SlotConfig07        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x24) {
    			Serial.print(F("         SlotConfig08        |       SlotConfig09        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x28) {
    			Serial.print(F("         SlotConfig0A        |       SlotConfig0B        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x2C) {
    			Serial.print(F("         SlotConfig0C        |       SlotConfig0D        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x30) {
    			Serial.print(F("         SlotConfig0E        |       SlotConfig0F        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x34) {
    			Serial.print(F("  UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x38) {
    			Serial.print(F("  UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x3C) {
    			Serial.print(F("  UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x40) {
    			Serial.print(F("  UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x44) {
    			Serial.print(F("                      LastKeyUse[0:3]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x48) {
    			Serial.print(F("                      LastKeyUse[4:7]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x4C) {
    			Serial.print(F("                      LastKeyUse[8:B]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x50) {
    			Serial.print(F("                      LastKeyUse[C:F]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x54) {
    			Serial.print(F("  UserExtra  |    Selector   | LockValue |  LockConfig   | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		}
    	}
    #endif // not USE_SOFT_SIGNING
    }
    
    /** @brief Sketch setup code */
    void setup()
    {
    	// Delay startup a bit for serial consoles to catch up
    	unsigned long enter = hwMillis();
    	while (hwMillis() - enter < (unsigned long)500);
    #ifndef USE_SOFT_SIGNING
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    	uint8_t lockConfig = 0;
    	uint8_t lockValue = 0;
    	uint16_t crc;
    	(void)crc;
    #else
    	// initialize pseudo-RNG
    	randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN));
    #endif
    	uint8_t key[32];
    	(void)key;
    
    	Serial.begin(115200);
    	hwInit();
    	Serial.println(F("Personalization sketch for MySensors usage."));
    	Serial.println(F("-------------------------------------------"));
    
    #ifndef USE_SOFT_SIGNING
    	// Wake device before starting operations
    	ret_code = sha204.sha204c_wakeup(rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to wake device. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	}
    	// Read out lock config bits to determine if locking is possible
    	ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to determine device lock status. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    		lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    	}
    #endif
    
    #ifdef STORE_SOFT_KEY
    #ifdef USER_SOFT_KEY
    	memcpy(key, user_soft_key_data, 32);
    	Serial.println(F("Using this user supplied soft HMAC key:"));
    #else
    	// Retrieve random value to use as soft HMAC key
    #ifdef USE_SOFT_SIGNING
    	for (int i = 0; i < 32; i++) {
    		key[i] = random(256) ^ micros();
    		unsigned long enter = hwMillis();
    		while (hwMillis() - enter < (unsigned long)2);
    	}
    	Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
    #else
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random key generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
    	} else {
    		Serial.println(F("Key is not randomized (configuration not locked):"));
    	}
    #endif // not USE_SOFT_SIGNING
    #endif // not USER_SOFT_KEY
    	Serial.print("#define MY_SOFT_HMAC_KEY ");
    	for (int i=0; i<32; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 31) {
    			Serial.print(',');
    		}
    	}
    	Serial.println();
    	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
    #endif // STORE_SOFT_KEY
    
    #ifdef STORE_SOFT_SERIAL
    #ifdef USER_SOFT_SERIAL
    	memcpy(key, user_soft_serial, 9);
    	Serial.println(F("Using this user supplied soft serial:"));
    #else
    	// Retrieve random value to use as serial
    #ifdef USE_SOFT_SIGNING
    	for (int i = 0; i < 9; i++) {
    		key[i] = random(256) ^ micros();
    		unsigned long enter = hwMillis();
    		while (hwMillis() - enter < (unsigned long)2);
    	}
    	Serial.println(F("This value will be stored in EEPROM as soft serial:"));
    #else
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random serial generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("This value will be stored in EEPROM as soft serial:"));
    	} else {
    		Serial.println(F("Serial is not randomized (configuration not locked):"));
    	}
    #endif // not USE_SOFT_SIGNING
    #endif // not USER_SOFT_SERIAL
    	Serial.print("#define MY_SOFT_SERIAL ");
    	for (int i=0; i<9; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 8) {
    			Serial.print(',');
    		}
    	}
    	Serial.println();
    	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
    #endif // STORE_SOFT_SERIAL
    
    #ifdef STORE_AES_KEY
    #ifdef USER_AES_KEY
    	memcpy(key, user_aes_key, 16);
    	Serial.println(F("Using this user supplied AES key:"));
    #else
    	// Retrieve random value to use as key
    #ifdef USE_SOFT_SIGNING
    	for (int i = 0; i < 16; i++) {
    		key[i] = random(256) ^ micros();
    		unsigned long enter = hwMillis();
    		while (hwMillis() - enter < (unsigned long)2);
    	}
    	Serial.println(F("This key will be stored in EEPROM as AES key:"));
    #else
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random key generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("This key will be stored in EEPROM as AES key:"));
    	} else {
    		Serial.println(F("Key is not randomized (configuration not locked):"));
    	}
    #endif // not USE_SOFT_SIGNING
    #endif // not USER_AES_KEY
    	Serial.print("#define MY_AES_KEY ");
    	for (int i=0; i<16; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 15) {
    			Serial.print(',');
    		}
    	}
    	Serial.println();
    	hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
    #endif // STORE_AES_KEY
    
    #ifdef USE_SOFT_SIGNING
    	Serial.println(F("EEPROM configuration:"));
    	dump_configuration();
    #else
    	// Output device revision on console
    	ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to determine device revision. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		Serial.print(F("Device revision: "));
    		for (int i=0; i<4; i++) {
    			if (rx_buffer[SHA204_BUFFER_POS_DATA+i] < 0x10) {
    				Serial.print('0'); // Because Serial.print does not 0-pad HEX
    			}
    			Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+i], HEX);
    		}
    		Serial.println();
    	}
    
    	// Output serial number on console
    	ret_code = sha204.getSerialNumber(rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to obtain device serial number. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		Serial.print(F("Device serial:   "));
    		Serial.print('{');
    		for (int i=0; i<9; i++) {
    			Serial.print(F("0x"));
    			if (rx_buffer[i] < 0x10) {
    				Serial.print('0'); // Because Serial.print does not 0-pad HEX
    			}
    			Serial.print(rx_buffer[i], HEX);
    			if (i < 8) {
    				Serial.print(',');
    			}
    		}
    		Serial.print('}');
    		Serial.println();
    		for (int i=0; i<9; i++) {
    			if (rx_buffer[i] < 0x10) {
    				Serial.print('0'); // Because Serial.print does not 0-pad HEX
    			}
    			Serial.print(rx_buffer[i], HEX);
    		}
    		Serial.println();
    	}
    
    	if (lockConfig != 0x00) {
    		// Write config and get CRC for the updated config
    		crc = write_config_and_get_crc();
    
    		// List current configuration before attempting to lock
    		Serial.println(F("Chip configuration:"));
    		dump_configuration();
    
    #ifdef LOCK_CONFIGURATION
    		// Purge serial input buffer
    #ifndef SKIP_UART_CONFIRMATION
    		while (Serial.available()) {
    			Serial.read();
    		}
    		Serial.println(F("Send SPACE character now to lock the configuration..."));
    
    		while (Serial.available() == 0);
    		if (Serial.read() == ' ')
    #endif //not SKIP_UART_CONFIRMATION
    		{
    			Serial.println(F("Locking configuration..."));
    
    			// Correct sequence, resync chip
    			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
    			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
    				Serial.print(F("Resync failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    
    			// Lock configuration zone
    			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
    			                                  crc, 0, NULL, 0, NULL, 0, NULL,
    			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Configuration lock failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			} else {
    				Serial.println(F("Configuration locked."));
    
    				// Update lock flags after locking
    				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
    				if (ret_code != SHA204_SUCCESS) {
    					Serial.print(F("Failed to determine device lock status. Response: "));
    					Serial.println(ret_code, HEX);
    					halt();
    				} else {
    					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    				}
    			}
    		}
    #ifndef SKIP_UART_CONFIRMATION
    		else {
    			Serial.println(F("Unexpected answer. Skipping lock."));
    		}
    #endif //not SKIP_UART_CONFIRMATION
    #else //LOCK_CONFIGURATION
    		Serial.println(F("Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
    #endif
    	} else {
    		Serial.println(F("Skipping configuration write and lock (configuration already locked)."));
    		Serial.println(F("Chip configuration:"));
    		dump_configuration();
    	}
    
    #ifdef SKIP_KEY_STORAGE
    	Serial.println(F("Disable SKIP_KEY_STORAGE to store key."));
    #else
    #ifdef USER_KEY
    	memcpy(key, user_key_data, 32);
    	Serial.println(F("Using this user supplied HMAC key:"));
    #else
    	// Retrieve random value to use as key
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random key generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("Take note of this key, it will never be the shown again:"));
    	} else {
    		Serial.println(F("Key is not randomized (configuration not locked):"));
    	}
    #endif
    	Serial.print("#define MY_HMAC_KEY ");
    	for (int i=0; i<32; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 31) {
    			Serial.print(',');
    		}
    		if (i+1 == 16) {
    			Serial.print("\\\n                    ");
    		}
    	}
    	Serial.println();
    
    	// It will not be possible to write the key if the configuration zone is unlocked
    	if (lockConfig == 0x00) {
    		// Write the key to the appropriate slot in the data zone
    		Serial.println(F("Writing key to slot 0..."));
    		write_key(key);
    	} else {
    		Serial.println(F("Skipping key storage (configuration not locked)."));
    		Serial.println(F("The configuration must be locked to be able to write a key."));
    	}
    #endif
    
    	if (lockValue != 0x00) {
    #ifdef LOCK_DATA
    #ifndef SKIP_UART_CONFIRMATION
    		while (Serial.available()) {
    			Serial.read();
    		}
    		Serial.println(F("Send SPACE character to lock data..."));
    		while (Serial.available() == 0);
    		if (Serial.read() == ' ')
    #endif //not SKIP_UART_CONFIRMATION
    		{
    			// Correct sequence, resync chip
    			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
    			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
    				Serial.print(F("Resync failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    
    			// If configuration is unlocked, key is not updated. Locking data in this case will cause
    			// slot 0 to contain an unknown (or factory default) key, and this is in practically any
    			// usecase not the desired behaviour, so ask for additional confirmation in this case.
    			if (lockConfig != 0x00) {
    				while (Serial.available()) {
    					Serial.read();
    				}
    				Serial.println(F("*** ATTENTION ***"));
    				Serial.println(F("Configuration is not locked. Are you ABSULOUTELY SURE you want to lock data?"));
    				Serial.println(F("Locking data at this stage will cause slot 0 to contain a factory default key"));
    				Serial.println(
    				    F("which cannot be change after locking is done. This is in practically any usecase"));
    				Serial.println(F("NOT the desired behavour. Send SPACE character now to lock data anyway..."));
    				while (Serial.available() == 0);
    				if (Serial.read() != ' ') {
    					Serial.println(F("Unexpected answer. Skipping lock."));
    					halt();
    				}
    			}
    
    			// Lock data zone
    			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_DATA | LOCK_ZONE_NO_CRC,
    			                                  0x0000, 0, NULL, 0, NULL, 0, NULL,
    			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Data lock failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			} else {
    				Serial.println(F("Data locked."));
    
    				// Update lock flags after locking
    				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
    				if (ret_code != SHA204_SUCCESS) {
    					Serial.print(F("Failed to determine device lock status. Response: "));
    					Serial.println(ret_code, HEX);
    					halt();
    				} else {
    					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    				}
    			}
    		}
    #ifndef SKIP_UART_CONFIRMATION
    		else {
    			Serial.println(F("Unexpected answer. Skipping lock."));
    		}
    #endif //not SKIP_UART_CONFIRMATION
    #else //LOCK_DATA
    		Serial.println(F("Data not locked. Define LOCK_DATA to lock for real."));
    #endif
    	} else {
    		Serial.println(F("Skipping OTP/data zone lock (zone already locked)."));
    	}
    #endif // not USE_SOFT_SIGNING
    
    	Serial.println(F("--------------------------------"));
    	Serial.println(F("Personalization is now complete."));
    #ifndef USE_SOFT_SIGNING
    	Serial.print(F("Configuration is "));
    	if (lockConfig == 0x00) {
    		Serial.println("LOCKED");
    	} else {
    		Serial.println("UNLOCKED");
    	}
    	Serial.print(F("Data is "));
    	if (lockValue == 0x00) {
    		Serial.println("LOCKED");
    	} else {
    		Serial.println("UNLOCKED");
    	}
    #endif
    }
    
    /** @brief Sketch execution code */
    void loop()
    {
    }```

  • Contest Winner

    @meddie Sorry, missed that post.
    You have SKIP_KEY_STORAGE defined so no keys will be stored. This is the default and intentional, to avoid people just executing the sketch and accidentally overwrite existing keys.
    Furthermore, you have selected to personalize a ATSHA device, and have it generate the keys. That means that you have to define LOCK_CONFIGURATION or the ATSHA random number generator will not work.


  • Contest Winner

    You can read about personalization here.



  • Ah, thank you very much, yes now i get generated a key. But one more question the AES key will not be generated? I got only the HMAC Key, do i have to put the AES Key at myself?
    Thank you very much!


  • Contest Winner

    @meddie Please read the documentation and the sketch carefully. It quite clearly states in both documentation and code that you need to define STORE_AES_KEY to generate and store an AES key.



  • @Anticimex
    sorry sorry for so many questions, i have read the how to use already some times, but maybe its my bad english or the fear to do something wrong or to destroy the chip. I get a little bit unsure.

    Now i get both keys. If i understood correctly, the keys are now stored, i have now to put the shown keys to the sketch as HMAC and AES Key, and run this sketch on the sensor nodes.
    On the gateway on which i generated the keys i dont need to do anything more as to upload the gateway sketch ?
    Thank you very much for your support!


  • Contest Winner

    @meddie assuming you locked the configuration of the atsha, no you should not need to do more.



  • @Anticimex said in 💬 Sensebender Gateway:

    @meddie Sorry, missed that post.
    You have SKIP_KEY_STORAGE defined so no keys will be stored. This is the default and intentional, to avoid people just executing the sketch and accidentally overwrite existing keys.
    Furthermore, you have selected to personalize a ATSHA device, and have it generate the keys. That means that you have to define LOCK_CONFIGURATION or the ATSHA random number generator will not work.

    @Anticimex
    sorry i have one more question, because i didnt fully understand this. In the gettings started how to you wrote:

    Pick a “master” device with serial debug port.
    Set the following sketch configuration of the personalizer:
    ...
    
    Enable SKIP_KEY_STORAGE
    ...
    
    Execute the sketch on the “master” device to obtain a randomized key. Save this key to a secure location and keep it confidential so that you can retrieve it if you need to personalize more devices later on.
    Now reconfigure the sketch with these settings:
    ...
    Disable SKIP_KEY_STORAGE
    ...
    Put the saved key in the user_key_data variable.
    Now execute the sketch on all devices you want to personalize with this secret key.
    

    on the first run i have to enable SKIP_KEY_STORAGE so i removed the comments.
    But here in forum you write i have to disable this. After i has disabled it wroked fine for me.

    But now i have to run the sketch on my node, and i think i have to disable the SKIP function too, because i need that the keys will be stored in the node.

    So if i am right, the on both runs the SKIP function has to be commented out? Or i am wrong?
    Thank you.


  • Contest Winner

    @meddie If your read the text carefully it says:
    Set the following sketch configuration of the personalizer:
    ...
    Execute the sketch on the “master” device to obtain a randomized key. Save this key to a secure location and keep it confidential so that you can retrieve it if you need to personalize more devices later on.
    Now reconfigure the sketch with these settings:
    ...
    Now execute the sketch on all devices you want to personalize with this secret key.

    So in other words; you first use the settings described in the first setting, execute that once. Follow the instructions carefully. Write down the key you got. Then you reconfigure the sketch and execute it on all devices you want to personalize. That is, you execute it twice on the first device.
    I wrote that you need to undefine SKIP_KEY_STORAGE if you want to store a key. But the first set of instructions in the documentation is not saying that you are supposed to store a key. It says "Execute the sketch on the “master” device to obtain a randomized key."

    So the documentation is correct, and describe a flow where you personalize nodes and gateways with the minimum amount of changes needed. First you generate a key, and this step can actually be skipped altogether if you just make your own random key or password to use for HMAC/AES.
    Then you reconfigure the personalizer to use your generated (or selected) key and write it to all your devices.



  • @Anticimex
    but as i runned the sketch with SKIP_KEY_STORAGE defined, so no keys were generated.

    i did not like to say that the documentation is incorrect, i like your documentation and your work very well! i just didnt understand it!

    Thank you very much!
    Greets Eddie


  • Contest Winner

    @meddie are you sure you ran with the exact settings described for generating the keys? The SKIP_KEY_STORAGE flag does not prevent the keys from being generated. They are still printed in the serial log. It prevents the keys from being stored to the atsha204a device.



  • i fear to write again, but my fail story goes on 😞
    i have uploaded on the gateway this sketch:

    /**
    * The MySensors Arduino library handles the wireless radio link and protocol
    * between your home built sensors/actuators and HA controller of choice.
    * The sensors forms a self healing radio network with optional repeaters. Each
    * repeater and gateway builds a routing tables in EEPROM which keeps track of the
    * network topology allowing messages to be routed to nodes.
    *
    * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
    * Copyright (C) 2013-2015 Sensnology AB
    * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
    *
    * Documentation: http://www.mysensors.org
    * Support Forum: http://forum.mysensors.org
    *
    * This program is free software; you can redistribute it and/or
    * modify it under the terms of the GNU General Public License
    * version 2 as published by the Free Software Foundation.
    *
    *******************************
    *
    * REVISION HISTORY
    * Version 1.0 - Henrik EKblad
    * Contribution by a-lurker and Anticimex,
    * Contribution by Norbert Truchsess <norbert.truchsess@t-online.de>
    * Contribution by Tomas Hozza <thozza@gmail.com>
    *
    *
    * DESCRIPTION
    * The EthernetGateway sends data received from sensors to the ethernet link.
    * The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
    *
    * This GW code is designed for Sensebender GateWay / (Arduino Zero variant)
    *
    * Wire connections (OPTIONAL):
    * - Inclusion button should be connected to SW2
    *
    * LEDs on board (default assignments):
    * - Orange: USB RX/TX - Blink when receiving / transmitting on USB CDC device
    * - Yellow: RX  - Blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
    * - Green : TX  - Blink fast on radio message transmitted. In inclusion mode will blink slowly
    * - Red   : ERR - Fast blink on error during transmission error or recieve crc error
    * - Blue  : free - (use with LED_BLUE macro)
    *
    */
    
    #include <stdint.h>
    #include <pins_arduino.h>
    #define SKETCH_VERSION "0.2"
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    #define MY_DEBUG_VERBOSE_SIGNING
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    // Set LOW transmit power level as default, if you have an amplified NRF-module and
    // power your radio separately with a good regulator you can turn up PA level.
    //#define MY_RF24_PA_LEVEL RF24_PA_HIGH
    
    #define MY_SIGNING_ATSHA204
    //#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}}
    //#define MY_SIGNING_REQUEST_SIGNATURES
    #ifndef MY_SIGNING_SOFT_RANDOMSEED_PIN
    #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
    #endif                              
    #ifndef MY_SIGNING_ATSHA204_PIN
    #define MY_SIGNING_ATSHA204_PIN 17
    #endif        
    #define MY_RF24_ENABLE_ENCRYPTION
        
    // Enable gateway ethernet module type
    #define MY_GATEWAY_W5100
    
    // W5100 Ethernet module SPI enable (optional if using a shield/module that manages SPI_EN signal)
    //#define MY_W5100_SPI_EN 4
    
    // Enable Soft SPI for NRF radio (note different radio wiring is required)
    // The W5100 ethernet module seems to have a hard time co-operate with
    // radio on the same spi bus.
    #if !defined(MY_W5100_SPI_EN) && !defined(ARDUINO_ARCH_SAMD)
    #define MY_SOFTSPI
    #define MY_SOFT_SPI_SCK_PIN 14
    #define MY_SOFT_SPI_MISO_PIN 16
    #define MY_SOFT_SPI_MOSI_PIN 15
    #endif
    
    // When W5100 is connected we have to move CE/CSN pins for NRF radio
    #ifndef MY_RF24_CE_PIN
    #define MY_RF24_CE_PIN 5
    #endif
    #ifndef MY_RF24_CS_PIN
    #define MY_RF24_CS_PIN 6
    #endif
    
    // Enable to UDP
    //#define MY_USE_UDP
    
    #define MY_IP_ADDRESS 10,0,0,253   // If this is disabled, DHCP is used to retrieve address
    // Renewal period if using DHCP
    //#define MY_IP_RENEWAL_INTERVAL 60000
    // The port to keep open on node server mode / or port to contact in client mode
    #define MY_PORT 5003
    
    // Controller ip address. Enables client mode (default is "server" mode).
    // Also enable this if MY_USE_UDP is used and you want sensor data sent somewhere.
    //#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 254
    
    // The MAC address can be anything you want but should be unique on your network.
    // Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use.
    // Note that most of the Ardunio examples use  "DEAD BEEF FEED" for the MAC address.
    #define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
    
    // Enable inclusion mode
    #define MY_INCLUSION_MODE_FEATURE
    // Enable Inclusion mode button on gateway
    #define MY_INCLUSION_BUTTON_FEATURE
    
    // Inverses behavior of inclusion button (if using external pullup)
    //#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP
    
    // Set inclusion mode duration (in seconds)
    #define MY_INCLUSION_MODE_DURATION 60
    // Digital pin used for inclusion mode button
    //#define MY_INCLUSION_MODE_BUTTON_PIN  3
    
    // Set blinking period
    #define MY_DEFAULT_LED_BLINK_PERIOD 300
    
    // Inverses the behavior of leds
    //#define MY_WITH_LEDS_BLINKING_INVERSE
    
    // Flash leds on rx/tx/err
    // Uncomment to override default HW configurations
    //#define MY_DEFAULT_ERR_LED_PIN 4  // Error led pin
    //#define MY_DEFAULT_RX_LED_PIN  6  // Receive led pin
    //#define MY_DEFAULT_TX_LED_PIN  5  // the PCB, on board LED
    
    
    #if defined(MY_USE_UDP)
    #include <EthernetUdp.h>
    #endif
    #include <Ethernet.h>
    #include <MySensors.h>
    #include <SD.h>
    //#include <drivers/ATSHA204/ATSHA204.cpp>
    
    Sd2Card card;
    
    #define EEPROM_VERIFICATION_ADDRESS 0x01
    
    static uint8_t num_of_leds = 5;
    static uint8_t leds[] = {LED_BLUE, LED_RED, LED_GREEN, LED_YELLOW, LED_ORANGE};
    
    void setup()
    {
      // Setup locally attached sensors
    }
    
    void presentation()
    {
      // Present locally attached sensors
    }
    
    void loop()
    {
      // Send locally attached sensor data here
    }
    
    
    void preHwInit()
    {
    
      pinMode(MY_SWC1, INPUT_PULLUP);
      pinMode(MY_SWC2, INPUT_PULLUP);
      if (digitalRead(MY_SWC1) && digitalRead(MY_SWC2)) {
        return;
      }
    
      uint8_t tests = 0;
    
      for (int i=0; i< num_of_leds; i++) {
        pinMode(leds[i], OUTPUT);
      }
      uint8_t led_state = 0;
      if (digitalRead(MY_SWC1)) {
        while (!Serial) {
          digitalWrite(LED_BLUE, led_state);
          led_state ^= 0x01;
          delay(500);
        } // Wait for USB to be connected, before spewing out data.
      }
      digitalWrite(LED_BLUE, LOW);
      if (Serial) {
        Serial.println("Sensebender GateWay test routine");
        Serial.print("Mysensors core version : ");
        Serial.println(MYSENSORS_LIBRARY_VERSION);
        Serial.print("GateWay sketch version : ");
        Serial.println(SKETCH_VERSION);
        Serial.println("----------------------------------");
        Serial.println();
      }
      if (testSha204()) {
        digitalWrite(LED_GREEN, HIGH);
        tests++;
      }
      if (testSDCard()) {
        digitalWrite(LED_YELLOW, HIGH);
        tests++;
      }
    
      if (testEEProm()) {
        digitalWrite(LED_ORANGE, HIGH);
        tests++;
      }
      if (testAnalog()) {
        digitalWrite(LED_BLUE, HIGH);
        tests++;
      }
      if (tests == 4) {
        while(1) {
          for (int i=0; i<num_of_leds; i++) {
            digitalWrite(leds[i], HIGH);
            delay(200);
            digitalWrite(leds[i], LOW);
          }
        }
      } else {
        while (1) {
          digitalWrite(LED_RED, HIGH);
          delay(200);
          digitalWrite(LED_RED, LOW);
          delay(200);
        }
      }
    
    }
    
    bool testSha204()
    {
      uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
      uint8_t ret_code;
      if (Serial) {
        Serial.print("- > SHA204 ");
      }
      atsha204_init(MY_SIGNING_ATSHA204_PIN);
      ret_code = atsha204_wakeup(rx_buffer);
    
      if (ret_code == SHA204_SUCCESS) {
        ret_code = atsha204_getSerialNumber(rx_buffer);
        if (ret_code != SHA204_SUCCESS) {
          if (Serial) {
            Serial.println(F("Failed to obtain device serial number. Response: "));
          }
          Serial.println(ret_code, HEX);
        } else {
          if (Serial) {
            Serial.print(F("Ok (serial : "));
            for (int i=0; i<9; i++) {
              if (rx_buffer[i] < 0x10) {
                Serial.print('0'); // Because Serial.print does not 0-pad HEX
              }
              Serial.print(rx_buffer[i], HEX);
            }
            Serial.println(")");
          }
          return true;
        }
      } else {
        if (Serial) {
          Serial.println(F("Failed to wakeup SHA204"));
        }
      }
      return false;
    }
    
    bool testSDCard()
    {
      if (Serial) {
        Serial.print("- > SD CARD ");
      }
      if (!card.init(SPI_HALF_SPEED, MY_SDCARD_CS)) {
        if (Serial) {
          Serial.println("SD CARD did not initialize!");
        }
      } else {
        if (Serial) {
          Serial.print("SD Card initialized correct! - ");
          Serial.print("type detected : ");
          switch(card.type()) {
          case SD_CARD_TYPE_SD1:
            Serial.println("SD1");
            break;
          case SD_CARD_TYPE_SD2:
            Serial.println("SD2");
            break;
          case SD_CARD_TYPE_SDHC:
            Serial.println("SDHC");
            break;
          default:
            Serial.println("Unknown");
          }
        }
        return true;
      }
      return false;
    }
    
    bool testEEProm()
    {
      uint8_t eeprom_d1, eeprom_d2;
      SerialUSB.print(" -> EEPROM ");
      Wire.begin();
      eeprom_d1 = i2c_eeprom_read_byte(EEPROM_VERIFICATION_ADDRESS);
      delay(500);
      eeprom_d1 = ~eeprom_d1; // invert the bits
      i2c_eeprom_write_byte(EEPROM_VERIFICATION_ADDRESS, eeprom_d1);
      delay(500);
      eeprom_d2 = i2c_eeprom_read_byte(EEPROM_VERIFICATION_ADDRESS);
      if (eeprom_d1 == eeprom_d2) {
        SerialUSB.println("PASSED");
        i2c_eeprom_write_byte(EEPROM_VERIFICATION_ADDRESS, ~eeprom_d1);
        return true;
      }
      SerialUSB.println("FAILED!");
      return false;
    }
    
    bool testAnalog()
    {
      int bat_detect = analogRead(MY_BAT_DETECT);
      Serial.print("-> analog : ");
      Serial.print(bat_detect);
      if (bat_detect < 400 || bat_detect > 650) {
        Serial.println(" Failed");
        return false;
      }
      Serial.println(" Passed");
      return true;
    }
    


  • and on the node this sketch:

    /*
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     */
    #include <stdint.h>
    #include <pins_arduino.h>
    #define MY_DEBUG
    #define MY_DEBUG_VERBOSE_SIGNING
    #define MY_RADIO_NRF24
    //#define MY_SIGNING_SOFT
    #define MY_SIGNING_ATSHA204
    //#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}}
    #define MY_SIGNING_REQUEST_SIGNATURES
    #ifndef MY_SIGNING_SOFT_RANDOMSEED_PIN
    #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
    #endif
    #ifndef MY_SIGNING_ATSHA204_PIN
    #define MY_SIGNING_ATSHA204_PIN 17
    #endif
    #define MY_RF24_ENABLE_ENCRYPTION
    #include <MySensors.h>
    

    But the node does not connect and i get this on the serial monitor:

    0 MCO:BGN:INIT NODE,CP=RNNNAA-,VER=2.1.1
    4 TSM:INIT
    4 TSF:WUR:MS=0
    12 TSM:INIT:TSP OK
    14 TSF:SID:OK,ID=100
    16 TSM:FPAR
    18 Will not sign message for destination 255 as it does not require it
    67 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    2076 !TSM:FPAR:NO REPLY
    2078 TSM:FPAR
    2080 Will not sign message for destination 255 as it does not require it
    2127 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    4139 !TSM:FPAR:NO REPLY
    4141 TSM:FPAR
    4143 Will not sign message for destination 255 as it does not require it
    4190 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    6199 !TSM:FPAR:NO REPLY
    6201 TSM:FPAR
    6203 Will not sign message for destination 255 as it does not require it
    6250 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    8259 !TSM:FPAR:FAIL
    8261 TSM:FAIL:CNT=1
    8263 TSM:FAIL:PDT
    18266 TSM:FAIL:RE-INIT
    18268 TSM:INIT
    18276 TSM:INIT:TSP OK
    18278 TSF:SID:OK,ID=100
    18280 TSM:FPAR
    18282 Will not sign message for destination 255 as it does not require it
    18331 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    20340 !TSM:FPAR:NO REPLY
    20342 TSM:FPAR
    20344 Will not sign message for destination 255 as it does not require it
    20393 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    22403 !TSM:FPAR:NO REPLY
    22405 TSM:FPAR
    22407 Will not sign message for destination 255 as it does not require it
    22456 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    24465 !TSM:FPAR:NO REPLY
    24467 TSM:FPAR
    24469 Will not sign message for destination 255 as it does not require it
    24518 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    26527 !TSM:FPAR:FAIL
    26529 TSM:FAIL:CNT=2
    26531 TSM:FAIL:PDT
    36534 TSM:FAIL:RE-INIT
    36536 TSM:INIT
    36544 TSM:INIT:TSP OK
    36546 TSF:SID:OK,ID=100
    36548 TSM:FPAR
    36550 Will not sign message for destination 255 as it does not require it
    36599 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    38610 !TSM:FPAR:NO REPLY
    38612 TSM:FPAR
    38615 Will not sign message for destination 255 as it does not require it
    38664 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    40673 !TSM:FPAR:NO REPLY
    40675 TSM:FPAR
    40677 Will not sign message for destination 255 as it does not require it
    40726 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    42735 !TSM:FPAR:NO REPLY
    42737 TSM:FPAR
    42739 Will not sign message for destination 255 as it does not require it
    42788 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    44800 !TSM:FPAR:FAIL
    44802 TSM:FAIL:CNT=3
    44804 TSM:FAIL:PDT
    54808 TSM:FAIL:RE-INIT
    54810 TSM:INIT
    54818 TSM:INIT:TSP OK
    54820 TSF:SID:OK,ID=100
    54822 TSM:FPAR
    54824 Will not sign message for destination 255 as it does not require it
    54874 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    56883 !TSM:FPAR:NO REPLY
    56885 TSM:FPAR
    56887 Will not sign message for destination 255 as it does not require it
    56936 TSF:MSG:SEND,100-100-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    

    please help me once again
    Thank you


  • Contest Winner

    @meddie if you want your node to sign messages to the gateway you have to tell the gateway to require it. The log says that it does not require it and it is clear from your gateway sketch that you have disabled the requirement.
    Is that your problem?
    EDIT: I see that the messages are broadcasts, those will never be signed. So the "will not sign messages" are perfectly normal no matter how you configure your gateway in this case.
    The problem, at least based on the node log is that your node cannot find a parent to communicate with for some reason.


  • Contest Winner

    @meddie for parsing the log file you can use this tool


  • Contest Winner

    @meddie I also see that you fail to find parent. Have you verified that you had working node-gateway communication before you enabled signing?



  • @Anticimex
    Hi, i have just uploaded the GatewayW5100 Sketch to the Gateway and the HumidtyTemp Sketch to the Node and it works fine, but without signing and encryption.


  • Contest Winner

    @meddie You had encryption enabled when it failed? That could explain the failure of the broadcast if you did not have a matching setting between the nodes/gateway.



  • @Anticimex
    yes the encryption was enabled. Should i upload the personalized sketch again with my keys?


  • Contest Winner

    @meddie You can just run an unmodified personalizer to have it read the EEPROM contents. That way you can verify that all devices share the exact same AES key. Assuming a mismatch in the AES key was the reason for the problem.
    But I strongly encourage you to just enable one security feature at a time if you are not sure what you are doing or it will be hard to debug what is going wrong.



  • @Anticimex
    yes, i try to activate one feature and when it works the next. So i decided to activate the encryption and then when it works then i try to activate the signing. But first i would to check the keys like you said and when i now upload the securitypersonalization sketch unmodified i dont get any output on the serial monitor.
    😞


  • Contest Winner

    @meddie Well, you have to make the patch to the baud rate and the changes we discussed earlier. I presume you did something necessary since you got output previously.



  • @Anticimex
    when i run the personalizer sketch i see in all keys FFFFFF....... What does it mean that no keys are stored?


  • Contest Winner

    @meddie yes, that mean eeprom is in default state. The node has not been properly personalized.



  • @Anticimex
    ok, i think i know what went wrong! But i dont know how to fix it. On the first run when i tried came the prompt to sens space to lock configuration i did it.
    Now when i upload the modified personalization sketch with my keys i get this output on serial monitor:
    of course i removed my keys with xx!

    Device serial:   {0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX}
    xxxxxxxxxxxxxxxxxxxxx
    Skipping configuration write and lock (configuration already locked).
    Chip configuration:
    EEPROM DATA:
    SOFT_HMAC_KEY | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    SOFT_SERIAL   | FFFFFFFFFFFFFFFFFF
    AES_KEY       | XXFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    ATSHA204A DATA:
               SN[0:1]           |         SN[2:3]           | XX   XX | XX   XX   
                              Revnum                         | 00   09   04   00   
                              SN[4:7]                        | XX   XX   XX   XX   
        SN[8]    |  Reserved13   | I2CEnable | Reserved15    | EE | 10 | 00 | 00   
      I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | C8 | 00 | 55 | 00   
             SlotConfig00        |       SlotConfig01        | 8F   80 | 80   A1   
             SlotConfig02        |       SlotConfig03        | 82   E0 | A3   60   
             SlotConfig04        |       SlotConfig05        | 94   40 | A0   85   
             SlotConfig06        |       SlotConfig07        | 86   40 | 87   07   
             SlotConfig08        |       SlotConfig09        | 0F   00 | 89   F2   
             SlotConfig0A        |       SlotConfig0B        | 8A   7A | 0B   8B   
             SlotConfig0C        |       SlotConfig0D        | 0C   4C | DD   4D   
             SlotConfig0E        |       SlotConfig0F        | C2   42 | AF   8F   
      UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | FF | 00 | FF | 00   
      UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | FF | 00 | FF | 00   
      UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | FF | 00 | FF | 00   
      UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | FF | 00 | FF | 00   
                          LastKeyUse[0:3]                    | FF   FF   FF   FF   
                          LastKeyUse[4:7]                    | FF   FF   FF   FF   
                          LastKeyUse[8:B]                    | FF   FF   FF   FF   
                          LastKeyUse[C:F]                    | FF   FF   FF   FF   
      UserExtra  |    Selector   | LockValue |  LockConfig   | 00 | 00 | 55 | 00   
    Using this user supplied HMAC key:
    #define MY_HMAC_KEY 0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,\
                        0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx
    Writing key to slot 0...
    Data not locked. Define LOCK_DATA to lock for real.
    --------------------------------
    Personalization is now complete.
    Configuration is LOCKED
    Data is UNLOCKED
    

    i thin this is the reason:

    Skipping configuration write and lock (configuration already locked).
    

    and what i find very interestin that the first two signs of AES Key are correct the rest of them are FFFFF

    AES_KEY       | XXFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    

    is it possible to unlock the configuration or did i kill the chip?
    Thank you
    Greets Eddie


  • Contest Winner

    @meddie you cannot undo a lock, and you have to lock the chip in order to use it. And it is not an error that it reports chip is already locked since you have locked it already.
    Furthermore, AES key and eeprom has nothing to do with the atsha204a chip so the lock state of the chip is irrelevant.
    Now, why your AES key is only partially stored, I am not sure. But my bet would be that you have an error in the line where you define it in the sketch. A space or something like that.
    Finally, as long as you don't lock the data zone, and you don't tamper with the configuration bits for the atsha204a device, you cannot destroy the chip. You can always replace the hmac key, which is the only thing you program to the atsha using the personalizer. Except for the chip configuration bits, and those the sketch handles for you and once config is locked they are fixed in place.



  • @Anticimex
    i checked the sketch already few times but i dont see an error.
    here is the code i have only change my key with XX

    
    
    #include "sha204_library.h"
    #include "sha204_lib_return_codes.h"
    #define MY_CORE_ONLY
    #include <MySensors.h>
    
    #if DOXYGEN
    #define LOCK_CONFIGURATION
    #define LOCK_DATA
    #define SKIP_KEY_STORAGE
    #define USER_KEY
    #define SKIP_UART_CONFIRMATION
    #define USE_SOFT_SIGNING
    #define STORE_SOFT_KEY
    #define USER_SOFT_KEY
    #define STORE_SOFT_SERIAL
    #define USER_SOFT_SERIAL
    #define STORE_AES_KEY
    #define USER_AES_KEY
    #endif
    
    #define LOCK_CONFIGURATION
    
    //#define LOCK_DATA
    
    //#define SKIP_KEY_STORAGE
    
    #define USER_KEY
    
    //#define SKIP_UART_CONFIRMATION
    
    //#define USE_SOFT_SIGNING
    
    //#define STORE_SOFT_KEY
    
    //#define USER_SOFT_KEY
    
    //#define STORE_SOFT_SERIAL
    
    //#define USER_SOFT_SERIAL
    
    #define STORE_AES_KEY
    
    #define USER_AES_KEY
    
    #if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY)
    #error You have to define USER_KEY for boards that does not have UART
    #endif
    
    #ifdef USER_KEY
    /** @brief The user-defined HMAC key to use for personalization */
    #define MY_HMAC_KEY 0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX
    /** @brief The data to store in key slot 0 */
    const uint8_t user_key_data[32] = {MY_HMAC_KEY};
    #endif
    
    #ifdef USER_SOFT_KEY
    /** @brief The user-defined soft HMAC key to use for EEPROM personalization */
    #define MY_SOFT_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    /** @brief The data to store as soft HMAC key in EEPROM */
    const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY};
    #endif
    
    #ifdef USER_SOFT_SERIAL
    /** @brief The user-defined soft serial to use for EEPROM personalization */
    #define MY_SOFT_SERIAL 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    /** @brief The data to store as soft serial in EEPROM */
    const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
    #endif
    
    #ifdef USER_AES_KEY
    /** @brief The user-defined AES key to use for EEPROM personalization */
    #define MY_AES_KEY 0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX
    /** @brief The data to store as AES key in EEPROM */
    const uint8_t user_aes_key[16] = {MY_AES_KEY};
    #endif
    
    #ifndef USE_SOFT_SIGNING
    const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A
    atsha204Class sha204(sha204Pin);
    #endif
    
    /** @brief Print a error notice and halt the execution */
    void halt()
    {
    	Serial.println(F("Halting!"));
    	while(1);
    }
    
    #ifndef USE_SOFT_SIGNING
    
    uint16_t write_config_and_get_crc()
    {
    	uint16_t crc = 0;
    	uint8_t config_word[4];
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    	bool do_write;
    
    	for (int i=0; i < 88; i += 4) {
    		do_write = true;
    		if (i == 20) {
    			config_word[0] = 0x8F;
    			config_word[1] = 0x80;
    			config_word[2] = 0x80;
    			config_word[3] = 0xA1;
    		} else if (i == 24) {
    			config_word[0] = 0x82;
    			config_word[1] = 0xE0;
    			config_word[2] = 0xA3;
    			config_word[3] = 0x60;
    		} else if (i == 28) {
    			config_word[0] = 0x94;
    			config_word[1] = 0x40;
    			config_word[2] = 0xA0;
    			config_word[3] = 0x85;
    		} else if (i == 32) {
    			config_word[0] = 0x86;
    			config_word[1] = 0x40;
    			config_word[2] = 0x87;
    			config_word[3] = 0x07;
    		} else if (i == 36) {
    			config_word[0] = 0x0F;
    			config_word[1] = 0x00;
    			config_word[2] = 0x89;
    			config_word[3] = 0xF2;
    		} else if (i == 40) {
    			config_word[0] = 0x8A;
    			config_word[1] = 0x7A;
    			config_word[2] = 0x0B;
    			config_word[3] = 0x8B;
    		} else if (i == 44) {
    			config_word[0] = 0x0C;
    			config_word[1] = 0x4C;
    			config_word[2] = 0xDD;
    			config_word[3] = 0x4D;
    		} else if (i == 48) {
    			config_word[0] = 0xC2;
    			config_word[1] = 0x42;
    			config_word[2] = 0xAF;
    			config_word[3] = 0x8F;
    		} else if (i == 52 || i == 56 || i == 60 || i == 64) {
    			config_word[0] = 0xFF;
    			config_word[1] = 0x00;
    			config_word[2] = 0xFF;
    			config_word[3] = 0x00;
    		} else if (i == 68 || i == 72 || i == 76 || i == 80) {
    			config_word[0] = 0xFF;
    			config_word[1] = 0xFF;
    			config_word[2] = 0xFF;
    			config_word[3] = 0xFF;
    		} else {
    			// All other configs are untouched
    			ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Failed to read config. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    			// Set config_word to the read data
    			config_word[0] = rx_buffer[SHA204_BUFFER_POS_DATA+0];
    			config_word[1] = rx_buffer[SHA204_BUFFER_POS_DATA+1];
    			config_word[2] = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    			config_word[3] = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    			do_write = false;
    		}
    
    		// Update crc with CRC for the current word
    		crc = sha204.calculateAndUpdateCrc(4, config_word, crc);
    
    		// Write config word
    		if (do_write) {
    			ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_CONFIG,
    			                                  i >> 2, 4, config_word, 0, NULL, 0, NULL,
    			                                  WRITE_COUNT_SHORT, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Failed to write config word at address "));
    				Serial.print(i);
    				Serial.print(F(". Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    		}
    	}
    	return crc;
    }
    
    /**
     * @brief Write provided key to slot 0
     * @param key The key data to write
     */
    void write_key(uint8_t* key)
    {
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    
    	// Write key to slot 0
    	ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG,
    	                                  0, SHA204_ZONE_ACCESS_32, key, 0, NULL, 0, NULL,
    	                                  WRITE_COUNT_LONG, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to write key to slot 0. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	}
    }
    #endif // not USE_SOFT_SIGNING
    
    /** @brief Dump current configuration to UART */
    void dump_configuration()
    {
    	uint8_t buffer[32];
    #ifndef USE_SOFT_SIGNING
    	Serial.println(F("EEPROM DATA:"));
    #endif
    	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
    	Serial.print(F("SOFT_HMAC_KEY | "));
    	for (int j=0; j<32; j++) {
    		if (buffer[j] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(buffer[j], HEX);
    	}
    	Serial.println();
    	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
    	Serial.print(F("SOFT_SERIAL   | "));
    	for (int j=0; j<9; j++) {
    		if (buffer[j] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(buffer[j], HEX);
    	}
    	Serial.println();
    	hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
    	Serial.print(F("AES_KEY       | "));
    	for (int j=0; j<16; j++) {
    		if (buffer[j] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(buffer[j], HEX);
    	}
    	Serial.println();
    #ifndef USE_SOFT_SIGNING
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    	Serial.println(F("ATSHA204A DATA:"));
    	for (int i=0; i < 88; i += 4) {
    		ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
    		if (ret_code != SHA204_SUCCESS) {
    			Serial.print(F("Failed to read config. Response: "));
    			Serial.println(ret_code, HEX);
    			halt();
    		}
    		if (i == 0x00) {
    			Serial.print(F("           SN[0:1]           |         SN[2:3]           | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x04) {
    			Serial.print(F("                          Revnum                         | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x08) {
    			Serial.print(F("                          SN[4:7]                        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x0C) {
    			Serial.print(F("    SN[8]    |  Reserved13   | I2CEnable | Reserved15    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x10) {
    			Serial.print(F("  I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x14) {
    			Serial.print(F("         SlotConfig00        |       SlotConfig01        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x18) {
    			Serial.print(F("         SlotConfig02        |       SlotConfig03        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x1C) {
    			Serial.print(F("         SlotConfig04        |       SlotConfig05        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x20) {
    			Serial.print(F("         SlotConfig06        |       SlotConfig07        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x24) {
    			Serial.print(F("         SlotConfig08        |       SlotConfig09        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x28) {
    			Serial.print(F("         SlotConfig0A        |       SlotConfig0B        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x2C) {
    			Serial.print(F("         SlotConfig0C        |       SlotConfig0D        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x30) {
    			Serial.print(F("         SlotConfig0E        |       SlotConfig0F        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x34) {
    			Serial.print(F("  UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x38) {
    			Serial.print(F("  UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x3C) {
    			Serial.print(F("  UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x40) {
    			Serial.print(F("  UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x44) {
    			Serial.print(F("                      LastKeyUse[0:3]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x48) {
    			Serial.print(F("                      LastKeyUse[4:7]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x4C) {
    			Serial.print(F("                      LastKeyUse[8:B]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x50) {
    			Serial.print(F("                      LastKeyUse[C:F]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x54) {
    			Serial.print(F("  UserExtra  |    Selector   | LockValue |  LockConfig   | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		}
    	}
    #endif // not USE_SOFT_SIGNING
    }
    
    /** @brief Sketch setup code */
    void setup()
    {
    	// Delay startup a bit for serial consoles to catch up
    	unsigned long enter = hwMillis();
    	while (hwMillis() - enter < (unsigned long)500);
    #ifndef USE_SOFT_SIGNING
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    	uint8_t lockConfig = 0;
    	uint8_t lockValue = 0;
    	uint16_t crc;
    	(void)crc;
    #else
    	// initialize pseudo-RNG
    	randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN));
    #endif
    	uint8_t key[32];
    	(void)key;
    
      Serial.begin(9600);
    	hwInit();
    	Serial.println(F("Personalization sketch for MySensors usage."));
    	Serial.println(F("-------------------------------------------"));
    
    #ifndef USE_SOFT_SIGNING
    	// Wake device before starting operations
    	ret_code = sha204.sha204c_wakeup(rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to wake device. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	}
    	// Read out lock config bits to determine if locking is possible
    	ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to determine device lock status. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    		lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    	}
    #endif
    
    #ifdef STORE_SOFT_KEY
    #ifdef USER_SOFT_KEY
    	memcpy(key, user_soft_key_data, 32);
    	Serial.println(F("Using this user supplied soft HMAC key:"));
    #else
    	// Retrieve random value to use as soft HMAC key
    #ifdef USE_SOFT_SIGNING
    	for (int i = 0; i < 32; i++) {
    		key[i] = random(256) ^ micros();
    		unsigned long enter = hwMillis();
    		while (hwMillis() - enter < (unsigned long)2);
    	}
    	Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
    #else
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random key generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
    	} else {
    		Serial.println(F("Key is not randomized (configuration not locked):"));
    	}
    #endif // not USE_SOFT_SIGNING
    #endif // not USER_SOFT_KEY
    	Serial.print("#define MY_SOFT_HMAC_KEY ");
    	for (int i=0; i<32; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 31) {
    			Serial.print(',');
    		}
    	}
    	Serial.println();
    	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
    #endif // STORE_SOFT_KEY
    
    #ifdef STORE_SOFT_SERIAL
    #ifdef USER_SOFT_SERIAL
    	memcpy(key, user_soft_serial, 9);
    	Serial.println(F("Using this user supplied soft serial:"));
    #else
    	// Retrieve random value to use as serial
    #ifdef USE_SOFT_SIGNING
    	for (int i = 0; i < 9; i++) {
    		key[i] = random(256) ^ micros();
    		unsigned long enter = hwMillis();
    		while (hwMillis() - enter < (unsigned long)2);
    	}
    	Serial.println(F("This value will be stored in EEPROM as soft serial:"));
    #else
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random serial generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("This value will be stored in EEPROM as soft serial:"));
    	} else {
    		Serial.println(F("Serial is not randomized (configuration not locked):"));
    	}
    #endif // not USE_SOFT_SIGNING
    #endif // not USER_SOFT_SERIAL
    	Serial.print("#define MY_SOFT_SERIAL ");
    	for (int i=0; i<9; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 8) {
    			Serial.print(',');
    		}
    	}
    	Serial.println();
    	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
    #endif // STORE_SOFT_SERIAL
    
    #ifdef STORE_AES_KEY
    #ifdef USER_AES_KEY
    	memcpy(key, user_aes_key, 16);
    	Serial.println(F("Using this user supplied AES key:"));
    #else
    	// Retrieve random value to use as key
    #ifdef USE_SOFT_SIGNING
    	for (int i = 0; i < 16; i++) {
    		key[i] = random(256) ^ micros();
    		unsigned long enter = hwMillis();
    		while (hwMillis() - enter < (unsigned long)2);
    	}
    	Serial.println(F("This key will be stored in EEPROM as AES key:"));
    #else
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random key generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("This key will be stored in EEPROM as AES key:"));
    	} else {
    		Serial.println(F("Key is not randomized (configuration not locked):"));
    	}
    #endif // not USE_SOFT_SIGNING
    #endif // not USER_AES_KEY
    	Serial.print("#define MY_AES_KEY ");
    	for (int i=0; i<16; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 15) {
    			Serial.print(',');
    		}
    	}
    	Serial.println();
    	hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
    #endif // STORE_AES_KEY
    
    #ifdef USE_SOFT_SIGNING
    	Serial.println(F("EEPROM configuration:"));
    	dump_configuration();
    #else
    	// Output device revision on console
    	ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to determine device revision. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		Serial.print(F("Device revision: "));
    		for (int i=0; i<4; i++) {
    			if (rx_buffer[SHA204_BUFFER_POS_DATA+i] < 0x10) {
    				Serial.print('0'); // Because Serial.print does not 0-pad HEX
    			}
    			Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+i], HEX);
    		}
    		Serial.println();
    	}
    
    	// Output serial number on console
    	ret_code = sha204.getSerialNumber(rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to obtain device serial number. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		Serial.print(F("Device serial:   "));
    		Serial.print('{');
    		for (int i=0; i<9; i++) {
    			Serial.print(F("0x"));
    			if (rx_buffer[i] < 0x10) {
    				Serial.print('0'); // Because Serial.print does not 0-pad HEX
    			}
    			Serial.print(rx_buffer[i], HEX);
    			if (i < 8) {
    				Serial.print(',');
    			}
    		}
    		Serial.print('}');
    		Serial.println();
    		for (int i=0; i<9; i++) {
    			if (rx_buffer[i] < 0x10) {
    				Serial.print('0'); // Because Serial.print does not 0-pad HEX
    			}
    			Serial.print(rx_buffer[i], HEX);
    		}
    		Serial.println();
    	}
    
    	if (lockConfig != 0x00) {
    		// Write config and get CRC for the updated config
    		crc = write_config_and_get_crc();
    
    		// List current configuration before attempting to lock
    		Serial.println(F("Chip configuration:"));
    		dump_configuration();
    
    #ifdef LOCK_CONFIGURATION
    		// Purge serial input buffer
    #ifndef SKIP_UART_CONFIRMATION
    		while (Serial.available()) {
    			Serial.read();
    		}
    		Serial.println(F("Send SPACE character now to lock the configuration..."));
    
    		while (Serial.available() == 0);
    		if (Serial.read() == ' ')
    #endif //not SKIP_UART_CONFIRMATION
    		{
    			Serial.println(F("Locking configuration..."));
    
    			// Correct sequence, resync chip
    			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
    			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
    				Serial.print(F("Resync failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    
    			// Lock configuration zone
    			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
    			                                  crc, 0, NULL, 0, NULL, 0, NULL,
    			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Configuration lock failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			} else {
    				Serial.println(F("Configuration locked."));
    
    				// Update lock flags after locking
    				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
    				if (ret_code != SHA204_SUCCESS) {
    					Serial.print(F("Failed to determine device lock status. Response: "));
    					Serial.println(ret_code, HEX);
    					halt();
    				} else {
    					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    				}
    			}
    		}
    #ifndef SKIP_UART_CONFIRMATION
    		else {
    			Serial.println(F("Unexpected answer. Skipping lock."));
    		}
    #endif //not SKIP_UART_CONFIRMATION
    #else //LOCK_CONFIGURATION
    		Serial.println(F("Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
    #endif
    	} else {
    		Serial.println(F("Skipping configuration write and lock (configuration already locked)."));
    		Serial.println(F("Chip configuration:"));
    		dump_configuration();
    	}
    
    #ifdef SKIP_KEY_STORAGE
    	Serial.println(F("Disable SKIP_KEY_STORAGE to store key."));
    #else
    #ifdef USER_KEY
    	memcpy(key, user_key_data, 32);
    	Serial.println(F("Using this user supplied HMAC key:"));
    #else
    	// Retrieve random value to use as key
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random key generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("Take note of this key, it will never be the shown again:"));
    	} else {
    		Serial.println(F("Key is not randomized (configuration not locked):"));
    	}
    #endif
    	Serial.print("#define MY_HMAC_KEY ");
    	for (int i=0; i<32; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 31) {
    			Serial.print(',');
    		}
    		if (i+1 == 16) {
    			Serial.print("\\\n                    ");
    		}
    	}
    	Serial.println();
    
    	// It will not be possible to write the key if the configuration zone is unlocked
    	if (lockConfig == 0x00) {
    		// Write the key to the appropriate slot in the data zone
    		Serial.println(F("Writing key to slot 0..."));
    		write_key(key);
    	} else {
    		Serial.println(F("Skipping key storage (configuration not locked)."));
    		Serial.println(F("The configuration must be locked to be able to write a key."));
    	}
    #endif
    
    	if (lockValue != 0x00) {
    #ifdef LOCK_DATA
    #ifndef SKIP_UART_CONFIRMATION
    		while (Serial.available()) {
    			Serial.read();
    		}
    		Serial.println(F("Send SPACE character to lock data..."));
    		while (Serial.available() == 0);
    		if (Serial.read() == ' ')
    #endif //not SKIP_UART_CONFIRMATION
    		{
    			// Correct sequence, resync chip
    			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
    			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
    				Serial.print(F("Resync failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    
    			// If configuration is unlocked, key is not updated. Locking data in this case will cause
    			// slot 0 to contain an unknown (or factory default) key, and this is in practically any
    			// usecase not the desired behaviour, so ask for additional confirmation in this case.
    			if (lockConfig != 0x00) {
    				while (Serial.available()) {
    					Serial.read();
    				}
    				Serial.println(F("*** ATTENTION ***"));
    				Serial.println(F("Configuration is not locked. Are you ABSULOUTELY SURE you want to lock data?"));
    				Serial.println(F("Locking data at this stage will cause slot 0 to contain a factory default key"));
    				Serial.println(
    				    F("which cannot be change after locking is done. This is in practically any usecase"));
    				Serial.println(F("NOT the desired behavour. Send SPACE character now to lock data anyway..."));
    				while (Serial.available() == 0);
    				if (Serial.read() != ' ') {
    					Serial.println(F("Unexpected answer. Skipping lock."));
    					halt();
    				}
    			}
    
    			// Lock data zone
    			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_DATA | LOCK_ZONE_NO_CRC,
    			                                  0x0000, 0, NULL, 0, NULL, 0, NULL,
    			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Data lock failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			} else {
    				Serial.println(F("Data locked."));
    
    				// Update lock flags after locking
    				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
    				if (ret_code != SHA204_SUCCESS) {
    					Serial.print(F("Failed to determine device lock status. Response: "));
    					Serial.println(ret_code, HEX);
    					halt();
    				} else {
    					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    				}
    			}
    		}
    #ifndef SKIP_UART_CONFIRMATION
    		else {
    			Serial.println(F("Unexpected answer. Skipping lock."));
    		}
    #endif //not SKIP_UART_CONFIRMATION
    #else //LOCK_DATA
    		Serial.println(F("Data not locked. Define LOCK_DATA to lock for real."));
    #endif
    	} else {
    		Serial.println(F("Skipping OTP/data zone lock (zone already locked)."));
    	}
    #endif // not USE_SOFT_SIGNING
    
    	Serial.println(F("--------------------------------"));
    	Serial.println(F("Personalization is now complete."));
    #ifndef USE_SOFT_SIGNING
    	Serial.print(F("Configuration is "));
    	if (lockConfig == 0x00) {
    		Serial.println("LOCKED");
    	} else {
    		Serial.println("UNLOCKED");
    	}
    	Serial.print(F("Data is "));
    	if (lockValue == 0x00) {
    		Serial.println("LOCKED");
    	} else {
    		Serial.println("UNLOCKED");
    	}
    #endif
    }
    
    /** @brief Sketch execution code */
    void loop()
    {
    }```


  • @Anticimex
    the interesting thing is when i upload the same sketch to the sensebender micro it works the AES Key will be stored correctly.
    But on the Sensebender Gateway only the first two digits


  • Contest Winner

    @meddie sorry, I cannot see anything out of the ordinary. What hardware do you run on? SAMD? I know the personalizer to work on AVR.
    Have you executed a sketch between personalizer rounds? Perhaps it overwrite parts of the eeprom.



  • @Anticimex
    the troubles i have on sensebender gateway its a samd. On the micro (avr based) works fine.
    On the gateway i didnt upload a sketch between. I have uploaded the personalizer sketch and after them i tried the unmoded personalizer.


  • Contest Winner

    @meddie ok, so samd hardware. @tbowmo is eeprom handling on samd fully compatible with avr? It would appear something is not quite right with eeprom writes (or reads) on samd.


  • Admin

    @Anticimex

    eeprom on samd is handled differently, than avr, since it's an external I2C eeprom. So the normal avr commands for read/write to the eeprom doesn't work.

    the pieces that handle eeprom is located in MyHwSAMD.cpp between line 45 and 100
    https://github.com/mysensors/MySensors/blob/development/core/MyHwSAMD.cpp#L45


  • Contest Winner

    @tbowmo
    That may be, but I would still expect hwReadConfigBlock and hwWriteConfigBlock to be chip agnostic.



  • @tbowmo
    sorry can you say me please what i have to add to the sketch that will store my aes key on the sensebender gateway?
    I am a very very noob
    thanks


  • Contest Winner

    @meddie could you please try an experiment?
    Configure the personalizer to use soft signing and store a soft hmac key and serial to eeprom? Just make up some numbers as keys and see if the same problem happen with those or if it is just the AES key that fail.



  • @Anticimex
    yes of course!!!
    here is the sketch:

    #include "sha204_library.h"
    #include "sha204_lib_return_codes.h"
    #define MY_CORE_ONLY
    #include <MySensors.h>
    
    // Doxygen specific constructs, not included when built normally
    // This is used to enable disabled macros/definitions to be included in the documentation as well.
    #if DOXYGEN
    #define LOCK_CONFIGURATION
    #define LOCK_DATA
    #define SKIP_KEY_STORAGE
    #define USER_KEY
    #define SKIP_UART_CONFIRMATION
    #define USE_SOFT_SIGNING
    #define STORE_SOFT_KEY
    #define USER_SOFT_KEY
    #define STORE_SOFT_SERIAL
    #define USER_SOFT_SERIAL
    #define STORE_AES_KEY
    #define USER_AES_KEY
    #endif
    
    #define LOCK_CONFIGURATION
    
    
    //#define LOCK_DATA
    
    
    //#define SKIP_KEY_STORAGE
    
    
    //#define USER_KEY
    
    
    //#define SKIP_UART_CONFIRMATION
    
    
    #define USE_SOFT_SIGNING
    
    
    #define STORE_SOFT_KEY
    
    
    #define USER_SOFT_KEY
    
    
    #define STORE_SOFT_SERIAL
    
    
    #define USER_SOFT_SERIAL
    
    
    #define STORE_AES_KEY
    
    
    //#define USER_AES_KEY
    
    #if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY)
    #error You have to define USER_KEY for boards that does not have UART
    #endif
    
    #ifdef USER_KEY
    /** @brief The user-defined HMAC key to use for personalization */
    #define MY_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    /** @brief The data to store in key slot 0 */
    const uint8_t user_key_data[32] = {MY_HMAC_KEY};
    #endif
    
    #ifdef USER_SOFT_KEY
    /** @brief The user-defined soft HMAC key to use for EEPROM personalization */
    #define MY_SOFT_HMAC_KEY 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x010,0x11,0x12,0x13,0x14,0x15,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xAA,0xAB,0xBA,0xBB,0xAC,0xAD,0xAE,0xEB,0xEC,0xED,0xDD
    /** @brief The data to store as soft HMAC key in EEPROM */
    const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY};
    #endif
    
    #ifdef USER_SOFT_SERIAL
    /** @brief The user-defined soft serial to use for EEPROM personalization */
    #define MY_SOFT_SERIAL 0x10,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02
    /** @brief The data to store as soft serial in EEPROM */
    const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
    #endif
    
    #ifdef USER_AES_KEY
    /** @brief The user-defined AES key to use for EEPROM personalization */
    #define MY_AES_KEY 0x15,0x14,0x13,0x12,0x11,0x10,0x09,0x08,0x07,0x06,0x05,0x05,0x04,0x03,0x14,0x15
    /** @brief The data to store as AES key in EEPROM */
    const uint8_t user_aes_key[16] = {MY_AES_KEY};
    #endif
    
    #ifndef USE_SOFT_SIGNING
    const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A
    atsha204Class sha204(sha204Pin);
    #endif
    
    /** @brief Print a error notice and halt the execution */
    void halt()
    {
    	Serial.println(F("Halting!"));
    	while(1);
    }
    
    #ifndef USE_SOFT_SIGNING
    
    uint16_t write_config_and_get_crc()
    {
    	uint16_t crc = 0;
    	uint8_t config_word[4];
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    	bool do_write;
    
    	
    	for (int i=0; i < 88; i += 4) {
    		do_write = true;
    		if (i == 20) {
    			config_word[0] = 0x8F;
    			config_word[1] = 0x80;
    			config_word[2] = 0x80;
    			config_word[3] = 0xA1;
    		} else if (i == 24) {
    			config_word[0] = 0x82;
    			config_word[1] = 0xE0;
    			config_word[2] = 0xA3;
    			config_word[3] = 0x60;
    		} else if (i == 28) {
    			config_word[0] = 0x94;
    			config_word[1] = 0x40;
    			config_word[2] = 0xA0;
    			config_word[3] = 0x85;
    		} else if (i == 32) {
    			config_word[0] = 0x86;
    			config_word[1] = 0x40;
    			config_word[2] = 0x87;
    			config_word[3] = 0x07;
    		} else if (i == 36) {
    			config_word[0] = 0x0F;
    			config_word[1] = 0x00;
    			config_word[2] = 0x89;
    			config_word[3] = 0xF2;
    		} else if (i == 40) {
    			config_word[0] = 0x8A;
    			config_word[1] = 0x7A;
    			config_word[2] = 0x0B;
    			config_word[3] = 0x8B;
    		} else if (i == 44) {
    			config_word[0] = 0x0C;
    			config_word[1] = 0x4C;
    			config_word[2] = 0xDD;
    			config_word[3] = 0x4D;
    		} else if (i == 48) {
    			config_word[0] = 0xC2;
    			config_word[1] = 0x42;
    			config_word[2] = 0xAF;
    			config_word[3] = 0x8F;
    		} else if (i == 52 || i == 56 || i == 60 || i == 64) {
    			config_word[0] = 0xFF;
    			config_word[1] = 0x00;
    			config_word[2] = 0xFF;
    			config_word[3] = 0x00;
    		} else if (i == 68 || i == 72 || i == 76 || i == 80) {
    			config_word[0] = 0xFF;
    			config_word[1] = 0xFF;
    			config_word[2] = 0xFF;
    			config_word[3] = 0xFF;
    		} else {
    			// All other configs are untouched
    			ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Failed to read config. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    			// Set config_word to the read data
    			config_word[0] = rx_buffer[SHA204_BUFFER_POS_DATA+0];
    			config_word[1] = rx_buffer[SHA204_BUFFER_POS_DATA+1];
    			config_word[2] = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    			config_word[3] = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    			do_write = false;
    		}
    
    		// Update crc with CRC for the current word
    		crc = sha204.calculateAndUpdateCrc(4, config_word, crc);
    
    		// Write config word
    		if (do_write) {
    			ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_CONFIG,
    			                                  i >> 2, 4, config_word, 0, NULL, 0, NULL,
    			                                  WRITE_COUNT_SHORT, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Failed to write config word at address "));
    				Serial.print(i);
    				Serial.print(F(". Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    		}
    	}
    	return crc;
    }
    
    
    void write_key(uint8_t* key)
    {
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    
    	// Write key to slot 0
    	ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG,
    	                                  0, SHA204_ZONE_ACCESS_32, key, 0, NULL, 0, NULL,
    	                                  WRITE_COUNT_LONG, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to write key to slot 0. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	}
    }
    #endif // not USE_SOFT_SIGNING
    
    /** @brief Dump current configuration to UART */
    void dump_configuration()
    {
    	uint8_t buffer[32];
    #ifndef USE_SOFT_SIGNING
    	Serial.println(F("EEPROM DATA:"));
    #endif
    	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
    	Serial.print(F("SOFT_HMAC_KEY | "));
    	for (int j=0; j<32; j++) {
    		if (buffer[j] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(buffer[j], HEX);
    	}
    	Serial.println();
    	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
    	Serial.print(F("SOFT_SERIAL   | "));
    	for (int j=0; j<9; j++) {
    		if (buffer[j] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(buffer[j], HEX);
    	}
    	Serial.println();
    	hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
    	Serial.print(F("AES_KEY       | "));
    	for (int j=0; j<16; j++) {
    		if (buffer[j] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(buffer[j], HEX);
    	}
    	Serial.println();
    #ifndef USE_SOFT_SIGNING
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    	Serial.println(F("ATSHA204A DATA:"));
    	for (int i=0; i < 88; i += 4) {
    		ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
    		if (ret_code != SHA204_SUCCESS) {
    			Serial.print(F("Failed to read config. Response: "));
    			Serial.println(ret_code, HEX);
    			halt();
    		}
    		if (i == 0x00) {
    			Serial.print(F("           SN[0:1]           |         SN[2:3]           | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x04) {
    			Serial.print(F("                          Revnum                         | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x08) {
    			Serial.print(F("                          SN[4:7]                        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x0C) {
    			Serial.print(F("    SN[8]    |  Reserved13   | I2CEnable | Reserved15    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x10) {
    			Serial.print(F("  I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x14) {
    			Serial.print(F("         SlotConfig00        |       SlotConfig01        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x18) {
    			Serial.print(F("         SlotConfig02        |       SlotConfig03        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x1C) {
    			Serial.print(F("         SlotConfig04        |       SlotConfig05        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x20) {
    			Serial.print(F("         SlotConfig06        |       SlotConfig07        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x24) {
    			Serial.print(F("         SlotConfig08        |       SlotConfig09        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x28) {
    			Serial.print(F("         SlotConfig0A        |       SlotConfig0B        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x2C) {
    			Serial.print(F("         SlotConfig0C        |       SlotConfig0D        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x30) {
    			Serial.print(F("         SlotConfig0E        |       SlotConfig0F        | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j == 1) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x34) {
    			Serial.print(F("  UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x38) {
    			Serial.print(F("  UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x3C) {
    			Serial.print(F("  UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x40) {
    			Serial.print(F("  UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		} else if (i == 0x44) {
    			Serial.print(F("                      LastKeyUse[0:3]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x48) {
    			Serial.print(F("                      LastKeyUse[4:7]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x4C) {
    			Serial.print(F("                      LastKeyUse[8:B]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x50) {
    			Serial.print(F("                      LastKeyUse[C:F]                    | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				Serial.print(F("   "));
    			}
    			Serial.println();
    		} else if (i == 0x54) {
    			Serial.print(F("  UserExtra  |    Selector   | LockValue |  LockConfig   | "));
    			for (int j=0; j<4; j++) {
    				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
    					Serial.print('0'); // Because Serial.print does not 0-pad HEX
    				}
    				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
    				if (j < 3) {
    					Serial.print(F(" | "));
    				} else {
    					Serial.print(F("   "));
    				}
    			}
    			Serial.println();
    		}
    	}
    #endif // not USE_SOFT_SIGNING
    }
    
    /** @brief Sketch setup code */
    void setup()
    {
    	// Delay startup a bit for serial consoles to catch up
    	unsigned long enter = hwMillis();
    	while (hwMillis() - enter < (unsigned long)500);
    #ifndef USE_SOFT_SIGNING
    	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
    	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
    	uint8_t ret_code;
    	uint8_t lockConfig = 0;
    	uint8_t lockValue = 0;
    	uint16_t crc;
    	(void)crc;
    #else
    	// initialize pseudo-RNG
    	randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN));
    #endif
    	uint8_t key[32];
    	(void)key;
    
    	Serial.begin(9600);
    	hwInit();
    	Serial.println(F("Personalization sketch for MySensors usage."));
    	Serial.println(F("-------------------------------------------"));
    
    #ifndef USE_SOFT_SIGNING
    	// Wake device before starting operations
    	ret_code = sha204.sha204c_wakeup(rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to wake device. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	}
    	// Read out lock config bits to determine if locking is possible
    	ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to determine device lock status. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    		lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    	}
    #endif
    
    #ifdef STORE_SOFT_KEY
    #ifdef USER_SOFT_KEY
    	memcpy(key, user_soft_key_data, 32);
    	Serial.println(F("Using this user supplied soft HMAC key:"));
    #else
    	// Retrieve random value to use as soft HMAC key
    #ifdef USE_SOFT_SIGNING
    	for (int i = 0; i < 32; i++) {
    		key[i] = random(256) ^ micros();
    		unsigned long enter = hwMillis();
    		while (hwMillis() - enter < (unsigned long)2);
    	}
    	Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
    #else
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random key generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
    	} else {
    		Serial.println(F("Key is not randomized (configuration not locked):"));
    	}
    #endif // not USE_SOFT_SIGNING
    #endif // not USER_SOFT_KEY
    	Serial.print("#define MY_SOFT_HMAC_KEY ");
    	for (int i=0; i<32; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 31) {
    			Serial.print(',');
    		}
    	}
    	Serial.println();
    	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
    #endif // STORE_SOFT_KEY
    
    #ifdef STORE_SOFT_SERIAL
    #ifdef USER_SOFT_SERIAL
    	memcpy(key, user_soft_serial, 9);
    	Serial.println(F("Using this user supplied soft serial:"));
    #else
    	// Retrieve random value to use as serial
    #ifdef USE_SOFT_SIGNING
    	for (int i = 0; i < 9; i++) {
    		key[i] = random(256) ^ micros();
    		unsigned long enter = hwMillis();
    		while (hwMillis() - enter < (unsigned long)2);
    	}
    	Serial.println(F("This value will be stored in EEPROM as soft serial:"));
    #else
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random serial generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("This value will be stored in EEPROM as soft serial:"));
    	} else {
    		Serial.println(F("Serial is not randomized (configuration not locked):"));
    	}
    #endif // not USE_SOFT_SIGNING
    #endif // not USER_SOFT_SERIAL
    	Serial.print("#define MY_SOFT_SERIAL ");
    	for (int i=0; i<9; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 8) {
    			Serial.print(',');
    		}
    	}
    	Serial.println();
    	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
    #endif // STORE_SOFT_SERIAL
    
    #ifdef STORE_AES_KEY
    #ifdef USER_AES_KEY
    	memcpy(key, user_aes_key, 16);
    	Serial.println(F("Using this user supplied AES key:"));
    #else
    	// Retrieve random value to use as key
    #ifdef USE_SOFT_SIGNING
    	for (int i = 0; i < 16; i++) {
    		key[i] = random(256) ^ micros();
    		unsigned long enter = hwMillis();
    		while (hwMillis() - enter < (unsigned long)2);
    	}
    	Serial.println(F("This key will be stored in EEPROM as AES key:"));
    #else
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random key generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("This key will be stored in EEPROM as AES key:"));
    	} else {
    		Serial.println(F("Key is not randomized (configuration not locked):"));
    	}
    #endif // not USE_SOFT_SIGNING
    #endif // not USER_AES_KEY
    	Serial.print("#define MY_AES_KEY ");
    	for (int i=0; i<16; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 15) {
    			Serial.print(',');
    		}
    	}
    	Serial.println();
    	hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
    #endif // STORE_AES_KEY
    
    #ifdef USE_SOFT_SIGNING
    	Serial.println(F("EEPROM configuration:"));
    	dump_configuration();
    #else
    	// Output device revision on console
    	ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to determine device revision. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		Serial.print(F("Device revision: "));
    		for (int i=0; i<4; i++) {
    			if (rx_buffer[SHA204_BUFFER_POS_DATA+i] < 0x10) {
    				Serial.print('0'); // Because Serial.print does not 0-pad HEX
    			}
    			Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+i], HEX);
    		}
    		Serial.println();
    	}
    
    	// Output serial number on console
    	ret_code = sha204.getSerialNumber(rx_buffer);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Failed to obtain device serial number. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		Serial.print(F("Device serial:   "));
    		Serial.print('{');
    		for (int i=0; i<9; i++) {
    			Serial.print(F("0x"));
    			if (rx_buffer[i] < 0x10) {
    				Serial.print('0'); // Because Serial.print does not 0-pad HEX
    			}
    			Serial.print(rx_buffer[i], HEX);
    			if (i < 8) {
    				Serial.print(',');
    			}
    		}
    		Serial.print('}');
    		Serial.println();
    		for (int i=0; i<9; i++) {
    			if (rx_buffer[i] < 0x10) {
    				Serial.print('0'); // Because Serial.print does not 0-pad HEX
    			}
    			Serial.print(rx_buffer[i], HEX);
    		}
    		Serial.println();
    	}
    
    	if (lockConfig != 0x00) {
    		// Write config and get CRC for the updated config
    		crc = write_config_and_get_crc();
    
    		// List current configuration before attempting to lock
    		Serial.println(F("Chip configuration:"));
    		dump_configuration();
    
    #ifdef LOCK_CONFIGURATION
    		// Purge serial input buffer
    #ifndef SKIP_UART_CONFIRMATION
    		while (Serial.available()) {
    			Serial.read();
    		}
    		Serial.println(F("Send SPACE character now to lock the configuration..."));
    
    		while (Serial.available() == 0);
    		if (Serial.read() == ' ')
    #endif //not SKIP_UART_CONFIRMATION
    		{
    			Serial.println(F("Locking configuration..."));
    
    			// Correct sequence, resync chip
    			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
    			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
    				Serial.print(F("Resync failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    
    			// Lock configuration zone
    			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
    			                                  crc, 0, NULL, 0, NULL, 0, NULL,
    			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Configuration lock failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			} else {
    				Serial.println(F("Configuration locked."));
    
    				// Update lock flags after locking
    				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
    				if (ret_code != SHA204_SUCCESS) {
    					Serial.print(F("Failed to determine device lock status. Response: "));
    					Serial.println(ret_code, HEX);
    					halt();
    				} else {
    					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    				}
    			}
    		}
    #ifndef SKIP_UART_CONFIRMATION
    		else {
    			Serial.println(F("Unexpected answer. Skipping lock."));
    		}
    #endif //not SKIP_UART_CONFIRMATION
    #else //LOCK_CONFIGURATION
    		Serial.println(F("Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
    #endif
    	} else {
    		Serial.println(F("Skipping configuration write and lock (configuration already locked)."));
    		Serial.println(F("Chip configuration:"));
    		dump_configuration();
    	}
    
    #ifdef SKIP_KEY_STORAGE
    	Serial.println(F("Disable SKIP_KEY_STORAGE to store key."));
    #else
    #ifdef USER_KEY
    	memcpy(key, user_key_data, 32);
    	Serial.println(F("Using this user supplied HMAC key:"));
    #else
    	// Retrieve random value to use as key
    	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
    	if (ret_code != SHA204_SUCCESS) {
    		Serial.print(F("Random key generation failed. Response: "));
    		Serial.println(ret_code, HEX);
    		halt();
    	} else {
    		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
    	}
    	if (lockConfig == 0x00) {
    		Serial.println(F("Take note of this key, it will never be the shown again:"));
    	} else {
    		Serial.println(F("Key is not randomized (configuration not locked):"));
    	}
    #endif
    	Serial.print("#define MY_HMAC_KEY ");
    	for (int i=0; i<32; i++) {
    		Serial.print("0x");
    		if (key[i] < 0x10) {
    			Serial.print('0'); // Because Serial.print does not 0-pad HEX
    		}
    		Serial.print(key[i], HEX);
    		if (i < 31) {
    			Serial.print(',');
    		}
    		if (i+1 == 16) {
    			Serial.print("\\\n                    ");
    		}
    	}
    	Serial.println();
    
    	// It will not be possible to write the key if the configuration zone is unlocked
    	if (lockConfig == 0x00) {
    		// Write the key to the appropriate slot in the data zone
    		Serial.println(F("Writing key to slot 0..."));
    		write_key(key);
    	} else {
    		Serial.println(F("Skipping key storage (configuration not locked)."));
    		Serial.println(F("The configuration must be locked to be able to write a key."));
    	}
    #endif
    
    	if (lockValue != 0x00) {
    #ifdef LOCK_DATA
    #ifndef SKIP_UART_CONFIRMATION
    		while (Serial.available()) {
    			Serial.read();
    		}
    		Serial.println(F("Send SPACE character to lock data..."));
    		while (Serial.available() == 0);
    		if (Serial.read() == ' ')
    #endif //not SKIP_UART_CONFIRMATION
    		{
    			// Correct sequence, resync chip
    			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
    			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
    				Serial.print(F("Resync failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			}
    
    			// If configuration is unlocked, key is not updated. Locking data in this case will cause
    			// slot 0 to contain an unknown (or factory default) key, and this is in practically any
    			// usecase not the desired behaviour, so ask for additional confirmation in this case.
    			if (lockConfig != 0x00) {
    				while (Serial.available()) {
    					Serial.read();
    				}
    				Serial.println(F("*** ATTENTION ***"));
    				Serial.println(F("Configuration is not locked. Are you ABSULOUTELY SURE you want to lock data?"));
    				Serial.println(F("Locking data at this stage will cause slot 0 to contain a factory default key"));
    				Serial.println(
    				    F("which cannot be change after locking is done. This is in practically any usecase"));
    				Serial.println(F("NOT the desired behavour. Send SPACE character now to lock data anyway..."));
    				while (Serial.available() == 0);
    				if (Serial.read() != ' ') {
    					Serial.println(F("Unexpected answer. Skipping lock."));
    					halt();
    				}
    			}
    
    			// Lock data zone
    			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_DATA | LOCK_ZONE_NO_CRC,
    			                                  0x0000, 0, NULL, 0, NULL, 0, NULL,
    			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
    			if (ret_code != SHA204_SUCCESS) {
    				Serial.print(F("Data lock failed. Response: "));
    				Serial.println(ret_code, HEX);
    				halt();
    			} else {
    				Serial.println(F("Data locked."));
    
    				// Update lock flags after locking
    				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
    				if (ret_code != SHA204_SUCCESS) {
    					Serial.print(F("Failed to determine device lock status. Response: "));
    					Serial.println(ret_code, HEX);
    					halt();
    				} else {
    					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
    					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
    				}
    			}
    		}
    #ifndef SKIP_UART_CONFIRMATION
    		else {
    			Serial.println(F("Unexpected answer. Skipping lock."));
    		}
    #endif //not SKIP_UART_CONFIRMATION
    #else //LOCK_DATA
    		Serial.println(F("Data not locked. Define LOCK_DATA to lock for real."));
    #endif
    	} else {
    		Serial.println(F("Skipping OTP/data zone lock (zone already locked)."));
    	}
    #endif // not USE_SOFT_SIGNING
    
    	Serial.println(F("--------------------------------"));
    	Serial.println(F("Personalization is now complete."));
    #ifndef USE_SOFT_SIGNING
    	Serial.print(F("Configuration is "));
    	if (lockConfig == 0x00) {
    		Serial.println("LOCKED");
    	} else {
    		Serial.println("UNLOCKED");
    	}
    	Serial.print(F("Data is "));
    	if (lockValue == 0x00) {
    		Serial.println("LOCKED");
    	} else {
    		Serial.println("UNLOCKED");
    	}
    #endif
    }
    
    /** @brief Sketch execution code */
    void loop()
    {
    }
    


  • @Anticimex
    and this is the serial output:

    This key will be stored in EEPROM as AES key:
    #define MY_AES_KEY 0x6A,0x2B,0xF7,0xFB,0x03,0x8D,0x03,0x85,0x4D,0xDA,0x2D,0x89,0x9F,0xAD,0x8B,0x4F
    EEPROM configuration:
    SOFT_HMAC_KEY | 01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    SOFT_SERIAL   | 10FFFFFFFFFFFFFFFF
    AES_KEY       | 6AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    --------------------------------
    Personalization is now complete.
    
    

  • Contest Winner

    @meddie ok, clearly there is some issue with eeprom storage on samd then.


  • Contest Winner

    We will investigate this further. Thanks for identifying the issue. Perhaps you could test signing with atsha on the gateway. That should work since it does not depend on eeprom.



  • @Anticimex
    thank you very much for your support and for your patience with me!!!!
    i just tried and the signing is working fine!!!!
    i look forward to try the encryption! i


  • Contest Winner

    @meddie you are so welcome! Glad that signing works for you. That is actually more complicated than encryption. We (the core team) have confirmed a problem with the write routine to the I2C eeprom on the SenseBender gateway. So people are investigating.


  • Contest Winner

    @meddie the development branch has been updated with a bug fix for the eeprom problem on samd based boards. If you pull the latest changes you should be able to properly personalize the AES key so that encryption will work.



  • @Anticimex
    Hi, i just tried it out and now it and it has worked! The Aes key is stored correctly! BUT i get now an error on compile the gateway sketch

    C:\Users\meddie\Documents\Arduino\SenseebnderGW_LAN_NRF24\SenseebnderGW_LAN_NRF24.ino\SenseebnderGW_LAN_NRF24.ino.ino: In function 'bool testEEProm()':
    
    SenseebnderGW_LAN_NRF24.ino:315: error: 'i2c_eeprom_read_byte' was not declared in this scope
    
       eeprom_d1 = i2c_eeprom_read_byte(EEPROM_VERIFICATION_ADDRESS);
    
                                                                   ^
    
    SenseebnderGW_LAN_NRF24.ino:318: error: 'i2c_eeprom_write_byte' was not declared in this scope
    
       i2c_eeprom_write_byte(EEPROM_VERIFICATION_ADDRESS, eeprom_d1);
    

    i could use the stable lib again then it should compile, but i think you would like to know that an error occours.
    Greets Eddie


  • Contest Winner

    @meddie thanks for reporting! @tbowmo something that slipped through the Jenkins filter?


  • Contest Winner

    @meddie the sketch you compile, is it from the MySensors library examples tree, the external examples repository, or a local sketch?



  • @Anticimex
    its combined from two example sketches sensebendergateway and gatewayw5100 example sketch


  • Contest Winner

    @meddie ok, if it is a local construction, it might be an expected error due to api changes in the library, in which case you need to update locally. The examples from the repository should compile ok.



  • i used the stable lib and comiled the sketch both features are now working encryption and signing! Thank you very much!!!!! I will try to update the example lib and try again.

    I got just the next problem the space from sensebender micro is not enought to use all three features signing, encryption and ota. When i use AES and Signing i get over 109%, when i use the example sketch temp and humidty meassure.

    Greets Eddie


  • Contest Winner

    @meddie you could consider using a conversion board (@tbowmo has published one at openhardware.io) and use rfm69 radios which do AES encryption in hw. It should put less strain on memory resources.



  • @Anticimex I am using a default SensebenderGatewaySerial sketch and get the following error when compiling:

    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:6:16: error: redefinition of 'uint8_t device_pin'
    
     static uint8_t device_pin;
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:6:16: error: 'uint8_t device_pin' previously declared here
    
     static uint8_t device_pin;
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'void swi_set_signal_pin(uint8_t)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:24:13: error: redefinition of 'void swi_set_signal_pin(uint8_t)'
    
     static void swi_set_signal_pin(uint8_t is_high)
    
                 ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:24:13: error: 'void swi_set_signal_pin(uint8_t)' previously defined here
    
     static void swi_set_signal_pin(uint8_t is_high)
    
                 ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t swi_send_bytes(uint8_t, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:35:16: error: redefinition of 'uint8_t swi_send_bytes(uint8_t, uint8_t*)'
    
     static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:35:16: error: 'uint8_t swi_send_bytes(uint8_t, uint8_t*)' previously defined here
    
     static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t swi_send_byte(uint8_t)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:74:16: error: redefinition of 'uint8_t swi_send_byte(uint8_t)'
    
     static uint8_t swi_send_byte(uint8_t value)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:74:16: error: 'uint8_t swi_send_byte(uint8_t)' previously defined here
    
     static uint8_t swi_send_byte(uint8_t value)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t swi_receive_bytes(uint8_t, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:79:16: error: redefinition of 'uint8_t swi_receive_bytes(uint8_t, uint8_t*)'
    
     static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:79:16: error: 'uint8_t swi_receive_bytes(uint8_t, uint8_t*)' previously defined here
    
     static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t sha204p_receive_response(uint8_t, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:178:16: error: redefinition of 'uint8_t sha204p_receive_response(uint8_t, uint8_t*)'
    
     static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:178:16: error: 'uint8_t sha204p_receive_response(uint8_t, uint8_t*)' previously defined here
    
     static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t sha204c_resync(uint8_t, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:212:16: error: redefinition of 'uint8_t sha204c_resync(uint8_t, uint8_t*)'
    
     static uint8_t sha204c_resync(uint8_t size, uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:212:16: error: 'uint8_t sha204c_resync(uint8_t, uint8_t*)' previously defined here
    
     static uint8_t sha204c_resync(uint8_t size, uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t sha204c_send_and_receive(uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:234:16: error: redefinition of 'uint8_t sha204c_send_and_receive(uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t)'
    
     static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer,
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:234:16: error: 'uint8_t sha204c_send_and_receive(uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t)' previously defined here
    
     static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer,
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t sha204m_read(uint8_t*, uint8_t*, uint8_t, uint16_t)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:379:16: error: redefinition of 'uint8_t sha204m_read(uint8_t*, uint8_t*, uint8_t, uint16_t)'
    
     static uint8_t sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:379:16: error: 'uint8_t sha204m_read(uint8_t*, uint8_t*, uint8_t, uint16_t)' previously defined here
    
     static uint8_t sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'void sha204c_calculate_crc(uint8_t, uint8_t*, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:399:13: error: redefinition of 'void sha204c_calculate_crc(uint8_t, uint8_t*, uint8_t*)'
    
     static void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc)
    
                 ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:399:13: error: 'void sha204c_calculate_crc(uint8_t, uint8_t*, uint8_t*)' previously defined here
    
     static void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc)
    
                 ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t sha204c_check_crc(uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:424:16: error: redefinition of 'uint8_t sha204c_check_crc(uint8_t*)'
    
     static uint8_t sha204c_check_crc(uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:424:16: error: 'uint8_t sha204c_check_crc(uint8_t*)' previously defined here
    
     static uint8_t sha204c_check_crc(uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'void atsha204_init(uint8_t)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:438:6: error: redefinition of 'void atsha204_init(uint8_t)'
    
     void atsha204_init(uint8_t pin)
    
          ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:438:6: error: 'void atsha204_init(uint8_t)' previously defined here
    
     void atsha204_init(uint8_t pin)
    
          ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'void atsha204_idle()':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:455:6: error: redefinition of 'void atsha204_idle()'
    
     void atsha204_idle(void)
    
          ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:455:6: error: 'void atsha204_idle()' previously defined here
    
     void atsha204_idle(void)
    
          ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'void atsha204_sleep()':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:460:6: error: redefinition of 'void atsha204_sleep()'
    
     void atsha204_sleep(void)
    
          ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:460:6: error: 'void atsha204_sleep()' previously defined here
    
     void atsha204_sleep(void)
    
          ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t atsha204_wakeup(uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:465:9: error: redefinition of 'uint8_t atsha204_wakeup(uint8_t*)'
    
     uint8_t atsha204_wakeup(uint8_t *response)
    
             ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:465:9: error: 'uint8_t atsha204_wakeup(uint8_t*)' previously defined here
    
     uint8_t atsha204_wakeup(uint8_t *response)
    
             ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t atsha204_execute(uint8_t, uint8_t, uint16_t, uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:495:9: error: redefinition of 'uint8_t atsha204_execute(uint8_t, uint8_t, uint16_t, uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t*)'
    
     uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
    
             ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:495:9: error: 'uint8_t atsha204_execute(uint8_t, uint8_t, uint16_t, uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t*)' previously defined here
    
     uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
    
             ^
    
    In file included from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:98:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t atsha204_getSerialNumber(uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:571:9: error: redefinition of 'uint8_t atsha204_getSerialNumber(uint8_t*)'
    
     uint8_t atsha204_getSerialNumber(uint8_t * response)
    
             ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\Documents\Arduino\SensebenderGatewaySerial-2.1.1\SensebenderGatewaySerial-2.1.1.ino:96:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:571:9: error: 'uint8_t atsha204_getSerialNumber(uint8_t*)' previously defined here
    
     uint8_t atsha204_getSerialNumber(uint8_t * response)
    
             ^
    
    Multiple libraries were found for "SD.h"
     Used: C:\Users\Alex\Documents\Arduino\libraries\SD
     Not used: C:\Program Files (x86)\Arduino\libraries\SD
    Using library MySensors at version 2.1.1 in folder: C:\Users\Alex\Documents\Arduino\libraries\MySensors 
    Using library Wire at version 1.0 in folder: C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\Wire 
    Using library SPI at version 1.0 in folder: C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\SPI 
    Using library SD at version 1.1.1 in folder: C:\Users\Alex\Documents\Arduino\libraries\SD 
    exit status 1
    Error compiling for board Sensebender Gateway.
    

    If I delete "#include <drivers/ATSHA204/ATSHA204.cpp>", it compiles just fine.
    Any ideas please?

    I am using Mysensors 2.1.1, Arduino IDE 1.8.1 and latest SAMD board def.


  • Contest Winner

    @alexsh1 That is because the sketch has this line

    #include <drivers/ATSHA204/ATSHA204.cpp>
    

    @tbowmo Is it intentional to include the cpp and not the header in the sketch?



  • @Anticimex Thanks! I can confirm it compiles fine with the header included rather than the cpp. I suppose it was not an intention


  • Admin

    @alexsh1

    What environment are you building in? platform.io ? Or?

    I know it's awkward to include the cpp file, but it must have been done intentional at some point in time, and arduino way of doing things are very weird at times..

    Btw it does compile fine for me (even with the .cpp as include)



  • @tbowmo No, I am just using Arduino IDE in Windows 10


  • Contest Winner

    I tried building the sketch in Arduino 1.8.1 on Windows 10. Worked fine here. In your log, the sketch name looks changed. It does not end with -2.1.1 here.

    Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\P\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\P\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Cloud\Google Drive\gits\libraries -fqbn=MySensors:samd:mysensors_gw_native -ide-version=10801 -build-path 
    ....
    "C:\Users\P\AppData\Local\Temp\arduino_build_482491/SensebenderGatewaySerial.ino.elf" "C:\Users\P\AppData\Local\Temp\arduino_build_482491\sketch\SensebenderGatewaySerial.ino.cpp.o" "C:\Users\P\AppData\Local\Temp\arduino_build_482491\libraries\Wire\Wire.cpp.o" "C:\Users\P\AppData\Local\Temp\arduino_build_482491\libraries\SPI\SPI.cpp.o" "C:\Users\P\AppData\Local\Temp\arduino_build_482491\libraries\SD\File.cpp.o" "C:\Users\P\AppData\Local\Temp\arduino_build_482491\libraries\SD\SD.cpp.o" "C:\Users\P\AppData\Local\Temp\arduino_build_482491\libraries\SD\utility\Sd2Card.cpp.o" "C:\Users\P\AppData\Local\Temp\arduino_build_482491\libraries\SD\utility\SdFile.cpp.o" "C:\Users\P\AppData\Local\Temp\arduino_build_482491\libraries\SD\utility\SdVolume.cpp.o" "C:\Users\P\AppData\Local\Temp\arduino_build_482491\core\variant.cpp.o" -Wl,--start-group "-LC:\Users\P\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.5.0/CMSIS/Lib/GCC/" -larm_cortexM0l_math -lm "C:\Users\P\AppData\Local\Temp\arduino_build_482491/core\core.a" -Wl,--end-group
    "C:\Users\P\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1/bin/arm-none-eabi-objcopy" -O binary  "C:\Users\P\AppData\Local\Temp\arduino_build_482491/SensebenderGatewaySerial.ino.elf" "C:\Users\P\AppData\Local\Temp\arduino_build_482491/SensebenderGatewaySerial.ino.bin"
    "C:\Users\P\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1/bin/arm-none-eabi-objcopy" -O ihex -R .eeprom  "C:\Users\P\AppData\Local\Temp\arduino_build_482491/SensebenderGatewaySerial.ino.elf" "C:\Users\P\AppData\Local\Temp\arduino_build_482491/SensebenderGatewaySerial.ino.hex"
    Multiple libraries were found for "SD.h"
     Used: C:\Cloud\Google Drive\gits\libraries\SD
     Not used: C:\Program Files (x86)\Arduino\libraries\SD
    Using library MySensors at version 2.1.1 in folder: C:\Cloud\Google Drive\gits\libraries\MySensors 
    Using library Wire at version 1.0 in folder: C:\Users\P\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\Wire 
    Using library SPI at version 1.0 in folder: C:\Users\P\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\SPI 
    Using library SD at version 1.1.1 in folder: C:\Cloud\Google Drive\gits\libraries\SD 
    Sketch uses 42984 bytes (16%) of program storage space. Maximum is 262144 bytes.
    


  • @Anticimex Sorry, my bad I forgot to mention that the sketch compiles OK as is.
    Only when I add signing:

    //#define MY_SIGNING
    #define MY_SIGNING_ATSHA204
    #define MY_SIGNING_REQUEST_SIGNATURES
    #define MY_SIGNING_ATSHA204_PIN 17
    

    It fails to compile:

    Arduino: 1.8.1 (Windows 10), Board: "Sensebender Gateway"
    
    C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\Alex\AppData\Local\Arduino15\packages -hardware C:\Users\Alex\Documents\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\Alex\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Alex\Documents\Arduino\libraries -fqbn=MySensors:samd:mysensors_gw_native -ide-version=10801 -build-path C:\Users\Alex\AppData\Local\Temp\arduino_build_806240 -warnings=none -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.openocd.path=C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\openocd\0.9.0-arduino5-static -prefs=runtime.tools.bossac.path=C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\bossac\1.7.0 -prefs=runtime.tools.CMSIS.path=C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.5.0 -prefs=runtime.tools.arm-none-eabi-gcc.path=C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1 -prefs=runtime.tools.CMSIS-Atmel.path=C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.1.0 -verbose C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino
    C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\Alex\AppData\Local\Arduino15\packages -hardware C:\Users\Alex\Documents\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\Alex\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Alex\Documents\Arduino\libraries -fqbn=MySensors:samd:mysensors_gw_native -ide-version=10801 -build-path C:\Users\Alex\AppData\Local\Temp\arduino_build_806240 -warnings=none -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.openocd.path=C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\openocd\0.9.0-arduino5-static -prefs=runtime.tools.bossac.path=C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\bossac\1.7.0 -prefs=runtime.tools.CMSIS.path=C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.5.0 -prefs=runtime.tools.arm-none-eabi-gcc.path=C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1 -prefs=runtime.tools.CMSIS-Atmel.path=C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.1.0 -verbose C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino
    Using board 'mysensors_gw_native' from platform in folder: C:\Users\Alex\AppData\Local\Arduino15\packages\MySensors\hardware\samd\1.0.5
    Using core 'arduino' from platform in folder: C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12
    WARNING: Spurious .mystools folder in 'MySensors' library
    Detecting libraries used...
    "C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1/bin/arm-none-eabi-g++" -mcpu=cortex-m0plus -mthumb -c -g -Os -w -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions  -w -x c++ -E -CC -DF_CPU=48000000L -DARDUINO=10801 -DARDUINO_SAMD_ZERO -DARDUINO_ARCH_SAMD  -D__SAMD21G18A__ -DUSB_VID=0x1209 -DUSB_PID=0x6949 -DUSBCON '-DUSB_MANUFACTURER="MySensors.org"' '-DUSB_PRODUCT="Sensebender GW"' "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.5.0/CMSIS/Include/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.1.0/CMSIS/Device/ATMEL/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\cores\arduino" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\MySensors\hardware\samd\1.0.5\variants\mysensors_gw" "C:\Users\Alex\AppData\Local\Temp\arduino_build_806240\sketch\SensebenderGatewaySerial.ino.cpp" -o "nul"
    "C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1/bin/arm-none-eabi-g++" -mcpu=cortex-m0plus -mthumb -c -g -Os -w -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions  -w -x c++ -E -CC -DF_CPU=48000000L -DARDUINO=10801 -DARDUINO_SAMD_ZERO -DARDUINO_ARCH_SAMD  -D__SAMD21G18A__ -DUSB_VID=0x1209 -DUSB_PID=0x6949 -DUSBCON '-DUSB_MANUFACTURER="MySensors.org"' '-DUSB_PRODUCT="Sensebender GW"' "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.5.0/CMSIS/Include/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.1.0/CMSIS/Device/ATMEL/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\cores\arduino" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\MySensors\hardware\samd\1.0.5\variants\mysensors_gw" "-IC:\Users\Alex\Documents\Arduino\libraries\MySensors" "C:\Users\Alex\AppData\Local\Temp\arduino_build_806240\sketch\SensebenderGatewaySerial.ino.cpp" -o "nul"
    "C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1/bin/arm-none-eabi-g++" -mcpu=cortex-m0plus -mthumb -c -g -Os -w -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions  -w -x c++ -E -CC -DF_CPU=48000000L -DARDUINO=10801 -DARDUINO_SAMD_ZERO -DARDUINO_ARCH_SAMD  -D__SAMD21G18A__ -DUSB_VID=0x1209 -DUSB_PID=0x6949 -DUSBCON '-DUSB_MANUFACTURER="MySensors.org"' '-DUSB_PRODUCT="Sensebender GW"' "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.5.0/CMSIS/Include/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.1.0/CMSIS/Device/ATMEL/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\cores\arduino" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\MySensors\hardware\samd\1.0.5\variants\mysensors_gw" "-IC:\Users\Alex\Documents\Arduino\libraries\MySensors" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\Wire" "C:\Users\Alex\AppData\Local\Temp\arduino_build_806240\sketch\SensebenderGatewaySerial.ino.cpp" -o "nul"
    "C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1/bin/arm-none-eabi-g++" -mcpu=cortex-m0plus -mthumb -c -g -Os -w -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions  -w -x c++ -E -CC -DF_CPU=48000000L -DARDUINO=10801 -DARDUINO_SAMD_ZERO -DARDUINO_ARCH_SAMD  -D__SAMD21G18A__ -DUSB_VID=0x1209 -DUSB_PID=0x6949 -DUSBCON '-DUSB_MANUFACTURER="MySensors.org"' '-DUSB_PRODUCT="Sensebender GW"' "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.5.0/CMSIS/Include/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.1.0/CMSIS/Device/ATMEL/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\cores\arduino" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\MySensors\hardware\samd\1.0.5\variants\mysensors_gw" "-IC:\Users\Alex\Documents\Arduino\libraries\MySensors" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\Wire" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\SPI" "C:\Users\Alex\AppData\Local\Temp\arduino_build_806240\sketch\SensebenderGatewaySerial.ino.cpp" -o "nul"
    "C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1/bin/arm-none-eabi-g++" -mcpu=cortex-m0plus -mthumb -c -g -Os -w -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions  -w -x c++ -E -CC -DF_CPU=48000000L -DARDUINO=10801 -DARDUINO_SAMD_ZERO -DARDUINO_ARCH_SAMD  -D__SAMD21G18A__ -DUSB_VID=0x1209 -DUSB_PID=0x6949 -DUSBCON '-DUSB_MANUFACTURER="MySensors.org"' '-DUSB_PRODUCT="Sensebender GW"' "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.5.0/CMSIS/Include/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.1.0/CMSIS/Device/ATMEL/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\cores\arduino" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\MySensors\hardware\samd\1.0.5\variants\mysensors_gw" "-IC:\Users\Alex\Documents\Arduino\libraries\MySensors" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\Wire" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\SPI" "-IC:\Users\Alex\Documents\Arduino\libraries\SD\src" "C:\Users\Alex\AppData\Local\Temp\arduino_build_806240\sketch\SensebenderGatewaySerial.ino.cpp" -o "nul"
    Using cached library dependencies for file: C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\Wire\Wire.cpp
    Using cached library dependencies for file: C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\SPI\SPI.cpp
    Using cached library dependencies for file: C:\Users\Alex\Documents\Arduino\libraries\SD\src\File.cpp
    Using cached library dependencies for file: C:\Users\Alex\Documents\Arduino\libraries\SD\src\SD.cpp
    Using cached library dependencies for file: C:\Users\Alex\Documents\Arduino\libraries\SD\src\utility\Sd2Card.cpp
    Using cached library dependencies for file: C:\Users\Alex\Documents\Arduino\libraries\SD\src\utility\SdFile.cpp
    Using cached library dependencies for file: C:\Users\Alex\Documents\Arduino\libraries\SD\src\utility\SdVolume.cpp
    Generating function prototypes...
    "C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1/bin/arm-none-eabi-g++" -mcpu=cortex-m0plus -mthumb -c -g -Os -w -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions  -w -x c++ -E -CC -DF_CPU=48000000L -DARDUINO=10801 -DARDUINO_SAMD_ZERO -DARDUINO_ARCH_SAMD  -D__SAMD21G18A__ -DUSB_VID=0x1209 -DUSB_PID=0x6949 -DUSBCON '-DUSB_MANUFACTURER="MySensors.org"' '-DUSB_PRODUCT="Sensebender GW"' "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.5.0/CMSIS/Include/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.1.0/CMSIS/Device/ATMEL/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\cores\arduino" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\MySensors\hardware\samd\1.0.5\variants\mysensors_gw" "-IC:\Users\Alex\Documents\Arduino\libraries\MySensors" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\Wire" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\SPI" "-IC:\Users\Alex\Documents\Arduino\libraries\SD\src" "C:\Users\Alex\AppData\Local\Temp\arduino_build_806240\sketch\SensebenderGatewaySerial.ino.cpp" -o "C:\Users\Alex\AppData\Local\Temp\arduino_build_806240\preproc\ctags_target_for_gcc_minus_e.cpp"
    "C:\Program Files (x86)\Arduino\tools-builder\ctags\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\Users\Alex\AppData\Local\Temp\arduino_build_806240\preproc\ctags_target_for_gcc_minus_e.cpp"
    Compiling sketch...
    "C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1/bin/arm-none-eabi-g++" -mcpu=cortex-m0plus -mthumb -c -g -Os -w -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD -DF_CPU=48000000L -DARDUINO=10801 -DARDUINO_SAMD_ZERO -DARDUINO_ARCH_SAMD  -D__SAMD21G18A__ -DUSB_VID=0x1209 -DUSB_PID=0x6949 -DUSBCON '-DUSB_MANUFACTURER="MySensors.org"' '-DUSB_PRODUCT="Sensebender GW"' "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS\4.5.0/CMSIS/Include/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.1.0/CMSIS/Device/ATMEL/" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\cores\arduino" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\MySensors\hardware\samd\1.0.5\variants\mysensors_gw" "-IC:\Users\Alex\Documents\Arduino\libraries\MySensors" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\Wire" "-IC:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\SPI" "-IC:\Users\Alex\Documents\Arduino\libraries\SD\src" "C:\Users\Alex\AppData\Local\Temp\arduino_build_806240\sketch\SensebenderGatewaySerial.ino.cpp" -o "C:\Users\Alex\AppData\Local\Temp\arduino_build_806240\sketch\SensebenderGatewaySerial.ino.cpp.o"
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:6:16: error: redefinition of 'uint8_t device_pin'
    
     static uint8_t device_pin;
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:6:16: error: 'uint8_t device_pin' previously declared here
    
     static uint8_t device_pin;
    
                    ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'void swi_set_signal_pin(uint8_t)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:24:13: error: redefinition of 'void swi_set_signal_pin(uint8_t)'
    
     static void swi_set_signal_pin(uint8_t is_high)
    
                 ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:24:13: error: 'void swi_set_signal_pin(uint8_t)' previously defined here
    
     static void swi_set_signal_pin(uint8_t is_high)
    
                 ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t swi_send_bytes(uint8_t, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:35:16: error: redefinition of 'uint8_t swi_send_bytes(uint8_t, uint8_t*)'
    
     static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:35:16: error: 'uint8_t swi_send_bytes(uint8_t, uint8_t*)' previously defined here
    
     static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer)
    
                    ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t swi_send_byte(uint8_t)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:74:16: error: redefinition of 'uint8_t swi_send_byte(uint8_t)'
    
     static uint8_t swi_send_byte(uint8_t value)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:74:16: error: 'uint8_t swi_send_byte(uint8_t)' previously defined here
    
     static uint8_t swi_send_byte(uint8_t value)
    
                    ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t swi_receive_bytes(uint8_t, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:79:16: error: redefinition of 'uint8_t swi_receive_bytes(uint8_t, uint8_t*)'
    
     static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:79:16: error: 'uint8_t swi_receive_bytes(uint8_t, uint8_t*)' previously defined here
    
     static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer)
    
                    ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t sha204p_receive_response(uint8_t, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:178:16: error: redefinition of 'uint8_t sha204p_receive_response(uint8_t, uint8_t*)'
    
     static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:178:16: error: 'uint8_t sha204p_receive_response(uint8_t, uint8_t*)' previously defined here
    
     static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t sha204c_resync(uint8_t, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:212:16: error: redefinition of 'uint8_t sha204c_resync(uint8_t, uint8_t*)'
    
     static uint8_t sha204c_resync(uint8_t size, uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:212:16: error: 'uint8_t sha204c_resync(uint8_t, uint8_t*)' previously defined here
    
     static uint8_t sha204c_resync(uint8_t size, uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t sha204c_send_and_receive(uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:234:16: error: redefinition of 'uint8_t sha204c_send_and_receive(uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t)'
    
     static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer,
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:234:16: error: 'uint8_t sha204c_send_and_receive(uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t)' previously defined here
    
     static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer,
    
                    ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t sha204m_read(uint8_t*, uint8_t*, uint8_t, uint16_t)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:379:16: error: redefinition of 'uint8_t sha204m_read(uint8_t*, uint8_t*, uint8_t, uint16_t)'
    
     static uint8_t sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:379:16: error: 'uint8_t sha204m_read(uint8_t*, uint8_t*, uint8_t, uint16_t)' previously defined here
    
     static uint8_t sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address)
    
                    ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'void sha204c_calculate_crc(uint8_t, uint8_t*, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:399:13: error: redefinition of 'void sha204c_calculate_crc(uint8_t, uint8_t*, uint8_t*)'
    
     static void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc)
    
                 ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:399:13: error: 'void sha204c_calculate_crc(uint8_t, uint8_t*, uint8_t*)' previously defined here
    
     static void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc)
    
                 ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t sha204c_check_crc(uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:424:16: error: redefinition of 'uint8_t sha204c_check_crc(uint8_t*)'
    
     static uint8_t sha204c_check_crc(uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:424:16: error: 'uint8_t sha204c_check_crc(uint8_t*)' previously defined here
    
     static uint8_t sha204c_check_crc(uint8_t *response)
    
                    ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'void atsha204_init(uint8_t)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:438:6: error: redefinition of 'void atsha204_init(uint8_t)'
    
     void atsha204_init(uint8_t pin)
    
          ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:438:6: error: 'void atsha204_init(uint8_t)' previously defined here
    
     void atsha204_init(uint8_t pin)
    
          ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'void atsha204_idle()':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:455:6: error: redefinition of 'void atsha204_idle()'
    
     void atsha204_idle(void)
    
          ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:455:6: error: 'void atsha204_idle()' previously defined here
    
     void atsha204_idle(void)
    
          ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'void atsha204_sleep()':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:460:6: error: redefinition of 'void atsha204_sleep()'
    
     void atsha204_sleep(void)
    
          ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:460:6: error: 'void atsha204_sleep()' previously defined here
    
     void atsha204_sleep(void)
    
          ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t atsha204_wakeup(uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:465:9: error: redefinition of 'uint8_t atsha204_wakeup(uint8_t*)'
    
     uint8_t atsha204_wakeup(uint8_t *response)
    
             ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:465:9: error: 'uint8_t atsha204_wakeup(uint8_t*)' previously defined here
    
     uint8_t atsha204_wakeup(uint8_t *response)
    
             ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t atsha204_execute(uint8_t, uint8_t, uint16_t, uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:495:9: error: redefinition of 'uint8_t atsha204_execute(uint8_t, uint8_t, uint16_t, uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t*)'
    
     uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
    
             ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:495:9: error: 'uint8_t atsha204_execute(uint8_t, uint8_t, uint16_t, uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t*)' previously defined here
    
     uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
    
             ^
    
    In file included from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:91:0:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp: In function 'uint8_t atsha204_getSerialNumber(uint8_t*)':
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:571:9: error: redefinition of 'uint8_t atsha204_getSerialNumber(uint8_t*)'
    
     uint8_t atsha204_getSerialNumber(uint8_t * response)
    
             ^
    
    In file included from C:\Users\Alex\Documents\Arduino\libraries\MySensors/MySensors.h:131:0,
    
                     from C:\Users\Alex\AppData\Local\Temp\arduino_modified_sketch_295317\SensebenderGatewaySerial.ino:89:
    
    C:\Users\Alex\Documents\Arduino\libraries\MySensors/drivers/ATSHA204/ATSHA204.cpp:571:9: error: 'uint8_t atsha204_getSerialNumber(uint8_t*)' previously defined here
    
     uint8_t atsha204_getSerialNumber(uint8_t * response)
    
             ^
    
    Multiple libraries were found for "SD.h"
     Used: C:\Users\Alex\Documents\Arduino\libraries\SD
     Not used: C:\Program Files (x86)\Arduino\libraries\SD
    Using library MySensors at version 2.1.1 in folder: C:\Users\Alex\Documents\Arduino\libraries\MySensors 
    Using library Wire at version 1.0 in folder: C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\Wire 
    Using library SPI at version 1.0 in folder: C:\Users\Alex\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.12\libraries\SPI 
    Using library SD at version 1.1.1 in folder: C:\Users\Alex\Documents\Arduino\libraries\SD 
    exit status 1
    Error compiling for board Sensebender Gateway.```

  • Admin

    Have you tried to comment the #include out?


Log in to reply
 

Suggested Topics

1
Online

11.4k
Users

11.1k
Topics

112.7k
Posts