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

Extending Buttonless DFU app to include UART. Fails when trying to advertise.

HIGH LEVEL: I am simply trying to build the ble_app_uart example on top of the Buttonless DFU example from the NRF SDK. I have confirmed that I can successfully get the default "Nordic_Buttonless" DFU example to work properly. When I try and add the Nordic UART Service to this Buttonless DFU example, I can see a successful DFU of my new app image is completed, yet the board never starts because of an error when it tries to advertise itself. Below are the code changes I have made to the Buttonless DFU example in order to add support for UART:

static ble_uuid_t m_adv_uuids[]         = 
{
    {BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE},
    {BLE_UUID_NUS_SERVICE, BLE_UUID_TYPE_VENDOR_BEGIN} // Same as: NUS_SERVICE_UUID_TYPE from ble_app_uart example code
};


static void nus_data_handler(ble_nus_evt_t * p_evt)
{
    // Added the basic default implementation from the ble_app_uart project
}


static void services_init(void)
{
    // NOTE: These lines of code have been ADDED to the default implementation!
    ble_nus_init_t     nus_init;

    // Initialize NUS.
    memset(&nus_init, 0, sizeof(nus_init));

    nus_init.data_handler = nus_data_handler;

    err_code = ble_nus_init(&m_nus, &nus_init);
    APP_ERROR_CHECK(err_code);
}

Also it should be noted that I have merged the sdk_configs and also made sure that NRF_SDH_BLE_VS_UUID_COUNT 2

The error I get comes from calling ble_advertising_init(). Following the Debugger through this function call, I am taken to ble_advdata_encode(). In this function, there is a comment that says // Encode 'complete' uuid list and in the following if-statement the Debugger steps into the execution of uuid_list_encode() and then again it steps into uuid_list_sized_encode() (for 16bit UUIDs). In uuid_list_sized_encode(), the error occurs with the call to sd_ble_uuid_encode(). The error produced is mostly SOFTDEVICE: INVALID MEMORY ACCESS (Info pointer has a value of 0x0), but I have also seen NRF_ERROR_INVALID_ADDR (Invalid pointer supplied) pop up a couple times. The error always occurs when trying to execute sd_ble_uuid_encode().

It seems to me that there is some issue with the way I am adding the NUS Service to the default Buttonless DFU app. When I tried adding the NUS Service as a BLE UUID Type in m_adv_uuids[], my custom app was able to actually advertise (Services: Device Information and 0001) even though I know UUID is not correct. Is something obviously incorrect with my array of uuids? Are there other crucial steps I need to take to add this UART UUID properly? What can I do to get this UART-extended Buttonless DFU app to run? Thank you in advance for your help!

  • Hi Corten, 

    Please make sure you call services_init before you call advertising_init. The reason is that you need to add the NUS UUID base to the softdevice before you can use the UUID type of it. 
    Also using the BLE_UUID_TYPE_VENDOR_BEGIN as the UUID type is not always correct. You should use what uuid_type value returned from sd_ble_uuid_vs_add() call. 
    If it's the first UUID base you register using sd_ble_uuid_vs_add() it will equal to BLE_UUID_TYPE_VENDOR_BEGIN . But if the second one then it will be BLE_UUID_TYPE_VENDOR_BEGIN  + 1 . 
    In this case when you combine NUS and Buttonless DFU, I suspect that the Buttonless DFU has already registered BLE_NORDIC_VENDOR_BASE_UUID using sd_ble_uuid_vs_add() and you may have an issue with the uuid_type. 

    Also, please aware that the advertising packet is only 31 bytes payload with a lot of overhead. If  you have a long device name, multiple UUIDs, it may not fit into one advertising packet. You may want to use the scan response if you want to include a 128 bit UUID in the advertising packets. 

  • I forgot to mention it but I already made my code call services_init() before advertising_init(). Doing this resolved a previous error I was getting about invalid parameters, but now I face this new and different error that I described above.

    I will try and change that use of BLE_UUID_TYPE_VENDOR_BEGIN. I only used that because it was the value used for the NUS Service in the ble_app_uart example code. And I confirm that the buttonless DFU init code is called before the nus init code in my services_init() func, so the DFU part calls sd_ble_uuid_vs_add() first. If this is what is truly happening, what should I do next to try and get this to work properly? How can I get it to advertise correctly? Is it just changing this VENDOR_BEGIN type?

    My device name that is advertised is just four letters "TLDB", and all I am adding is these 2 UUIDs. Should this fit into one advertising packet?

  • Hi Corten, 
    Please try to add the UUIDs to scan response packet and check if you can get it there. 

    If you have a look at sd_ble_uuid_vs_add() description you can find that p_uuid_type is the output. You need to save this value after you call and use this value when you add the UUID to the advertising packet. 

  • Thanks Hung. This makes sense. I am able to debug and verify that the ble_uuid.type is actually 0x03 rather than the VENDOR_BEGIN type, which is 0x02. I now save this uuid type that is returned from sd_ble_uuid_vs_add() and add this second UUID advertising information to the scan response data in the advertising_init() function before calling ble_advertising_init().

    `And my custom app now successfully advertises and can perform DFU!!!

Related