This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Changing Eddystone beacon frame type and data

Hi all,

Based on the EddystoneBeacon example (ble_app_eddystone), I try and change the advertising slot contents runtime from main.c on a button press. I read similar questions here in the Devzone, and as expected this pointed me to the usage of es_slot_on_write, but things don't work out as I want it to be. When I write the new data to slot 0, the application resets after reporting a Fatal error. When I write to slot 1, 2 or 3, nothing changes and the application keeps sending the earlier set Default data. Here is what I try to do in the Button event handle:

static uint8_t TestData[20] = {
APP_ES_UID_FRAME_TYPE, DEFAULT_FRAME_TX_POWER,
    0x33, 0x33, 0x44, 0x44, 0x55, 0x55, 0x44, 0x44, 0x33, 0x33, //10-byte UID namespace
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, //6-byte UID ID
    0x00, 0x00
};

/**@brief Function for handling button events from app_button IRQ
 *
 * @param[in] pin_no Pin of the button for which an event has occured
 * @param[in] button_action Press or Release
 */
static void button_evt_handler(uint8_t pin_no, uint8_t button_action)
{
    if (button_action == APP_BUTTON_PUSH && pin_no == BUTTON_1) {
// nrf_ble_es_on_start_connectable_advertising();
        es_slot_on_write(0, 20, TestData);
    }
    if (button_action == APP_BUTTON_PUSH && pin_no == BUTTON_2) {
        es_slot_on_write(1, 20, TestData);
    }
}

With some debug prints I see it ending up in configure_slot as should be, but it does not work so I must do something wrong:

  • Do I need to call extra functions to get this working as should be?
  • Can it be the TestData frame contents, are the test-values for the UID-Frame for some reason invalid?
  • Some other cause?

I'm using nrf52840-DK and nRF5 SDK v.16.0

Thanks in advance for your reply

  • OK, I think I have figured it out myself:

    Looking at the code for configure_slot in es_slot.c, it starts copying the data at

        uint8_t * p_data_after_ranging_data = ((uint8_t *)(&m_reg.slots[slot_no].adv_frame.frame) +
                                               RANGING_DATA_INDEX + RANGING_DATA_LENGTH);
    

    This is 2 bytes from the frame-start. And the actual copying is done like:

            case ES_FRAME_TYPE_URL:
                memcpy(p_data_after_ranging_data, &p_frame_data[1], length - 1);
    

    Which means that my TestData is one byte too long and should not include the Tx-Power. If I leave this byte out and pass a length of 19, no Fatal error occurs and the data is sent as should be. So apparently the es_slot_on-write does require a little different frame format as one (or at least I) would expect. For completeness the final (working) code:

    static const uint8_t TestDataUid[19] = {
    	APP_ES_UID_FRAME_TYPE,
    	0x33, 0x33, 0x44, 0x44, 0x55, 0x55, 0x44, 0x44, 0x33, 0x33,		//10-byte UID namespace
    	0x07, 0x07, 0x07, 0x07, 0x07, 0x07,								//6-byte UID ID
    	0x00, 0x00
    };
    
    static void button_evt_handler(uint8_t pin_no, uint8_t button_action)
    {
        if (button_action == APP_BUTTON_PUSH && pin_no == BUTTON_1) {
    //        nrf_ble_es_on_start_connectable_advertising();
    		es_slot_on_write(0, 19, TestDataUid);
        }
    }

    Hope this could help someone else. Regards

Related