This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

802.15.4 precompiled library limited

I based my project on the secure wireless uart example in the nrf5 SDK and linked to the precompiled gcc library 802_15_4_lib_gcc.a

I then tried to add multiple entries to the MAC tables in security.c using mac_table_item_set(). All goes well for the first 2 entries, but the 3rd generates a hard fault as the max table limit is hit (table_max_size). 

.text.table_max_size  0x0000000000013a58 0x34 ../../../nRF5_SDK/components/802_15_4/secure/802_15_4_lib_gcc.a(mac_mlme_pib_table.o)

According to the ,map file, this is part of the precompiled library, so I am unable to change it. Is there a way around this limit? How to I recompile this library?

Thanks,

Allan

Parents
  • Hi Allan,

    What is the error code returned by mac_table_item_set()? This will tell you whether the issue is because the table index is out of range or because there is not enough dynamic memory to put the item into the security table.

    What are you sending in as parameters of mac_table_item_set()? The id parameter is used to let mac_table_item_set() know the size of the new table item based on what type of table it is, such as MAC_KEY_TABLE, MAC_DEVICE_TABLE etc. If the table index parameter, idx, is larger than the size of the table item you will get an error that the table index is out of range, MAC_INVALID_INDEX. You can find the table sizes of the different types of tables in 802_15_4_config.h, such as CONFIG_MAC_DEVICE_TABLE_SIZE for MAC_DEVICE_TABLE.

    Best regards,

    Marte

  • Hi Marte,

     

    For the first 2 calls, mac_table_item_set() returns MAC_SUCCESS. For the third call, it does not return – it generates a hard fault.

     

    The call I use is shown below:

     

        /* Init the tables before adding to them */
        mac_table_init(&key_descr.id_lookup_list);
        mac_table_init(&key_descr.key_device_list);
        mac_table_init(&key_descr.key_usage_list);
    
        key_id_lookup_descr.size = KEY_LOOKUP_SIZE_FIVE;
    
        /* Add our entries to the tables */
        for (u8_cntr = 0; u8_cntr < MAX_PAIR_DEV; u8_cntr++)
        {
            memcpy(key_id_lookup_descr.data, a_KeyLookupData[u8_cntr], KEY_LOOKUP_SIZE_FIVE_VAL);
            status = mac_table_item_set(&key_descr.id_lookup_list,
                                        &key_id_lookup_descr.table_service,
                                        MAC_KEY_ID_LOOKUP_LIST, u8_cntr);
    
            ASSERT(status == MAC_SUCCESS);
    
            …
            
        }
     

    The settings from my 802_15_4_config.h:

     

    #define CONFIG_MAC_KEY_TABLE_SIZE 8
    #define CONFIG_MAC_DEVICE_TABLE_SIZE 8
    #define CONFIG_MAC_SECURITY_LEVEL_TABLE_SIZE 8
    #define CONFIG_MAC_KEY_ID_LOOKUP_LIST_SIZE 8
    #define CONFIG_MAC_KEY_DEVICE_LIST_SIZE 8
    #define CONFIG_MAC_KEY_USAGE_LIST_SIZE 8
    #define CONFIG_IEEE_ADDRESS 0x0123456789ABCDEFULL

    Thanks,

    Allan

  • Hi Allan,

    I am still looking into this, but I have not been able to find a solution yet. Due to holidays I will not be able to get in touch with the developers until the middle of next week, so it might take some time before I have a response unfortunately.

    Best regards,

    Marte

  • Hi Allan,

    Unfortunately the stack used by the IEEE 802.15.4 MAC library is developed by another company. Because of this we do not have access to the whole stack, and we do not have expertise regarding this library. Our developers recommend using the nRF IEEE 802.15.4 radio driver if possible, however, this does not have a MAC layer.

    It does not seem like the issue is with the size of the MAC key lookup list, as I was able to add multiple items when doing something similar to the code you shared here. I also used a_KeyLookupData, setting the size of it and MAX_PAIR_DEV to CONFIG_MAC_KEY_ID_LOOKUP_LIST_SIZE. However, I filled each entry with m_key_lookup_data, so it is possible that the issue is related to your a_KeyLookupData. How does the third element of a_KeyLookupData look like compared to the first and second, since this is the one that fails? 

    Best regards,

    Marte

  • Hi Marte,

    All 3 elements are identical in size, I just changed the index. I must be doing something wrong. Could you please post the snippet of your test code that worked? I might help me spot where I am going wrong. I suspect one of my items should be declared as an array, but as I can't see what the library functions are doing, I am not sure what it is expecting.

    Thanks,

    Allan

Reply
  • Hi Marte,

    All 3 elements are identical in size, I just changed the index. I must be doing something wrong. Could you please post the snippet of your test code that worked? I might help me spot where I am going wrong. I suspect one of my items should be declared as an array, but as I can't see what the library functions are doing, I am not sure what it is expecting.

    Thanks,

    Allan

Children
  • Hi Marte,

    I don't know if it all works yet, but I don't get the hard fault anymore. When I converted the function to be index based, I missed one instance.

        pib_id.mlme_id = MAC_KEY_TABLE;
        status = mlme_set(pib_id, 0, &key_descr);
        ASSERT(status == MAC_SUCCESS);
        
        *** should have been ***
        
        pib_id.mlme_id = MAC_KEY_TABLE;
        status = mlme_set(pib_id, u8_cntr, &key_descr);
        ASSERT(status == MAC_SUCCESS);

    Here is the code that is no longer crashing (fingers crossed it works now).

    #define GET_BYTE(x, n) (((x) >> (n * 8)) & 0xFF)
    
    typedef uint8_t key_data[KEY_LOOKUP_SIZE_FIVE_VAL];
    
    static key_data a_KeyLookupData[MAX_PAIR_DEV] = {\
        {GET_BYTE(CONFIG_PAN_ID, 0), GET_BYTE(CONFIG_PAN_ID, 1), GET_BYTE(1, 0), GET_BYTE(1, 1), 0x00},\
        {GET_BYTE(CONFIG_PAN_ID, 0), GET_BYTE(CONFIG_PAN_ID, 1), GET_BYTE(2, 0), GET_BYTE(2, 1), 0x00},\
        {GET_BYTE(CONFIG_PAN_ID, 0), GET_BYTE(CONFIG_PAN_ID, 1), GET_BYTE(CONFIG_OTHER_ADDRESS, 0), GET_BYTE(CONFIG_OTHER_ADDRESS, 1), 0x00},\
        {GET_BYTE(CONFIG_PAN_ID, 0), GET_BYTE(CONFIG_PAN_ID, 1), GET_BYTE(12, 0), GET_BYTE(12, 1), 0x00},\
        };
    
    const uint8_t m_security_key[MAC_SECURITY_KEY_SIZE] = CONFIG_SECURITY_KEY;
    
    void security_tables_init(void)
    {
    #if (CONFIG_SECURE == 1)
        uint8_t                    u8_cntr;
        pib_id_t                   id;
        bool                       security_enabled;
        mac_status_t               status;
        pib_id_t                   pib_id;
        mac_key_descr_t            key_descr;
        mac_key_id_lookup_descr_t  key_id_lookup_descr;
        mac_key_device_descr_t     key_device_descr;
        mac_key_usage_descr_t      key_usage_descr;
        mac_security_level_descr_t sec_level_descr;
        mac_device_descr_t         device_descr;
    
        id.mlme_id = MAC_SECURITY_ENABLED;
        security_enabled = true;
        mlme_set(id, 0, &security_enabled);
    
        /* Init the tables before adding to them */    
        mac_table_init(&key_descr.id_lookup_list);
        mac_table_init(&key_descr.key_device_list);
        mac_table_init(&key_descr.key_usage_list);
    
        key_id_lookup_descr.size = KEY_LOOKUP_SIZE_FIVE;
    
        /* Add our entries to the tables */
        for (u8_cntr = 0; u8_cntr < MAX_PAIR_DEV; u8_cntr++)
        {
            memcpy(key_id_lookup_descr.data, a_KeyLookupData[u8_cntr], KEY_LOOKUP_SIZE_FIVE_VAL);
            status = mac_table_item_set(&key_descr.id_lookup_list,
                                        &key_id_lookup_descr.table_service,
                                        MAC_KEY_ID_LOOKUP_LIST, u8_cntr);
            ASSERT(status == MAC_SUCCESS);
    
            key_device_descr.blacklisted = false;
            key_device_descr.unique_device = true;
            key_device_descr.device_handle = 0;
            key_device_descr.table_service.idx = u8_cntr;
            status = mac_table_item_set(&key_descr.key_device_list,
                                        &key_device_descr.table_service,
                                        MAC_KEY_DEVICE_LIST, u8_cntr);
            ASSERT(status == MAC_SUCCESS);
    
            key_usage_descr.frame_type = MAC_DATA;
            key_usage_descr.cmd_frame_id = 0;
            status = mac_table_item_set(&key_descr.key_usage_list,
                                        &key_usage_descr.table_service,
                                        MAC_KEY_USAGE_LIST, u8_cntr);
            ASSERT(status == MAC_SUCCESS);
    
            memcpy(key_descr.key, m_security_key, MAC_SECURITY_KEY_SIZE);
    
            pib_id.mlme_id = MAC_KEY_TABLE;
            status = mlme_set(pib_id, u8_cntr, &key_descr);
            ASSERT(status == MAC_SUCCESS);
    
            sec_level_descr.security_min = CONFIG_DATA_SECURITY_LEVEL;
            sec_level_descr.frame_type   = MAC_DATA;
            sec_level_descr.override_min = true;
    
            device_descr.extended_address = CONFIG_IEEE_ADDRESS + CONFIG_OTHER_ADDRESS;
            device_descr.pan_id           = CONFIG_PAN_ID;
            device_descr.short_address    = CONFIG_OTHER_ADDRESS;
            device_descr.frame_counter    = 0;
            device_descr.exempt           = 0;
    
            pib_id.mlme_id = MAC_DEVICE_TABLE;
            status = mlme_set(pib_id, u8_cntr, &device_descr);
            ASSERT(status == MAC_SUCCESS);
    
            pib_id.mlme_id = MAC_SECURITY_LEVEL_TABLE;
            status = mlme_set(pib_id, u8_cntr, &sec_level_descr);
            ASSERT(status == MAC_SUCCESS);
        }
    
        fsm_event_post(E_SET_DONE, NULL);
        (void)status;
    #endif
    }
    

  • Hi Allan,

    Good to hear that you are having progress! Have you been able to test to see if it works as expected, besides not crashing?

    My implementation was very close to yours. Instead of creating new items I simply added m_key_lookup_data to a_KeyLookupData:

    uint8_t *a_KeyLookupData[MAX_PAIR_DEV] = {m_key_lookup_data,
    									      m_key_lookup_data,
    									      m_key_lookup_data,
    									      m_key_lookup_data,
    									      m_key_lookup_data,
    									      m_key_lookup_data,
    									      m_key_lookup_data,
    									      m_key_lookup_data};

    And then I copied your for loop and added a line for logging as well to make sure that it looped through all items.

    I did not see any issues when I tested at least, but I did not test thoroughly enough to be able to say that it works for certain. 

    Best regards,

    Marte

  • Hi Marte

    Sadly it did not work. The first device in the table was able to communicate as normal, but the second could only receive packets. Packets sent from this device were received, but failed to be decoded and returned the following error code: 

    MAC_SECURITY_ERROR = 0xE4, /* 228 */ /**< Cryptographic processing of the
    received secured frame failed. */

    I have just got it working and have all 3 devices communicating. They key was that if you have more than 1 device in the list, you have to set :key_device_descr.unique_device = false;

    For future reference, here is the whole file where I have added 4 devices to my tables:

    #include "sdk_config.h"
    #include "802_15_4_config.h"
    #include "main.h"
    
    #include <string.h>
    #include "fsm.h"
    #include "mac_security.h"
    #include "mac_common.h"
    #include "mac_mlme_pib.h"
    #include "mac_mlme_comm_status.h"
    
    #define GET_BYTE(x, n) (((x) >> (n * 8)) & 0xFF)
    
    typedef uint8_t key_data[KEY_LOOKUP_SIZE_FIVE_VAL];
    
    /* Table of short addresses for my paired devices */
    const uint16_t au16_ShortAddressTable[MAX_PAIR_DEV] = {0xAE3F, 0x8A32, 0x1BEB, 0xC7B8};
    const uint8_t m_security_key[MAC_SECURITY_KEY_SIZE] = CONFIG_SECURITY_KEY;
    
    void security_tables_init(void)
    {
    #if (CONFIG_SECURE == 1)
        uint8_t                    u8_cntr;
        pib_id_t                   id;
        bool                       security_enabled;
        mac_status_t               status;
        pib_id_t                   pib_id;
        mac_key_descr_t            key_descr;
        mac_key_id_lookup_descr_t  key_id_lookup_descr;
        mac_key_device_descr_t     key_device_descr;
        mac_key_usage_descr_t      key_usage_descr;
        mac_security_level_descr_t sec_level_descr;
        mac_device_descr_t         device_descr;
        key_data                   KeyLookupData = {GET_BYTE(CONFIG_PAN_ID, 0), GET_BYTE(CONFIG_PAN_ID, 1), 0, 0, 0};
        uint16_t                   u16_ShortAddr;
    
        id.mlme_id = MAC_SECURITY_ENABLED;
        security_enabled = true;
        mlme_set(id, 0, &security_enabled);
    
        /* Init the tables before adding to them */    
        mac_table_init(&key_descr.id_lookup_list);
        mac_table_init(&key_descr.key_device_list);
        mac_table_init(&key_descr.key_usage_list);
    
        key_id_lookup_descr.size = KEY_LOOKUP_SIZE_FIVE;
    
        /* Add our entries to the tables */
        for (u8_cntr = 0; u8_cntr < MAX_PAIR_DEV; u8_cntr++)
        {
            /* Get the next short address to add and build a lookup key for it */
            u16_ShortAddr = au16_ShortAddressTable[u8_cntr];
            KeyLookupData[2] = GET_BYTE(u16_ShortAddr, 0);
            KeyLookupData[3] = GET_BYTE(u16_ShortAddr, 1);
    
            /* Add it to the table at the next index */
            memcpy(key_id_lookup_descr.data, KeyLookupData, KEY_LOOKUP_SIZE_FIVE_VAL);
            status = mac_table_item_set(&key_descr.id_lookup_list,
                                        &key_id_lookup_descr.table_service,
                                        MAC_KEY_ID_LOOKUP_LIST, u8_cntr);
            ASSERT(status == MAC_SUCCESS);
    
            key_device_descr.blacklisted = false;
            key_device_descr.unique_device = false;
            key_device_descr.device_handle = u8_cntr;
            key_device_descr.table_service.idx = u8_cntr;
            status = mac_table_item_set(&key_descr.key_device_list,
                                        &key_device_descr.table_service,
                                        MAC_KEY_DEVICE_LIST, u8_cntr);
            ASSERT(status == MAC_SUCCESS);
    
            key_usage_descr.frame_type = MAC_DATA;
            key_usage_descr.cmd_frame_id = 0;
            status = mac_table_item_set(&key_descr.key_usage_list,
                                        &key_usage_descr.table_service,
                                        MAC_KEY_USAGE_LIST, u8_cntr);
            ASSERT(status == MAC_SUCCESS);
    
            memcpy(key_descr.key, m_security_key, MAC_SECURITY_KEY_SIZE);
    
            pib_id.mlme_id = MAC_KEY_TABLE;
            status = mlme_set(pib_id, u8_cntr, &key_descr);
            ASSERT(status == MAC_SUCCESS);
    
            sec_level_descr.security_min = CONFIG_DATA_SECURITY_LEVEL;
            sec_level_descr.frame_type   = MAC_DATA;
            sec_level_descr.override_min = true;
    
            device_descr.extended_address = CONFIG_IEEE_ADDRESS + u16_ShortAddr;
            device_descr.pan_id           = CONFIG_PAN_ID;
            device_descr.short_address    = u16_ShortAddr;
            device_descr.frame_counter    = 0;
            device_descr.exempt           = 0;
    
            pib_id.mlme_id = MAC_DEVICE_TABLE;
            status = mlme_set(pib_id, u8_cntr, &device_descr);
            ASSERT(status == MAC_SUCCESS);
    
            pib_id.mlme_id = MAC_SECURITY_LEVEL_TABLE;
            status = mlme_set(pib_id, u8_cntr, &sec_level_descr);
            ASSERT(status == MAC_SUCCESS);
        }
    
        fsm_event_post(E_SET_DONE, NULL);
        (void)status;
    #endif
    }
    
    void mlme_comm_status_ind(mlme_comm_status_ind_t * ind)
    {
        printf("security status: %d\n\r", ind->status);
    }
    

  • Hi Allan,

    I am glad to hear that you managed to get it to work eventually. Thank you for sharing your solution here so others with the same issue can find it, it is highly appreciated!

    Best regards,

    Marte

Related