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

BLE mesh and FOTA upgrade

I am working with nRF Connect SDK using an nRF52840 DK. And I want to realise both BLE mesh and FOTA upgrade. FOTA upgrade example SMP Server Sample works properly for Bluetooth Low Energy (without any mesh). And now I want to integrate this FOTA upgrade into BLE mesh application. Please, tell me, how can I do it in the best way?
I had some attempts to realise it, however I faced some difficulties. I don't know how to stop mesh advertisement, which started by bt_mesh_prov_enable, and run ordinary BLE advertising by bt_le_adv_start. bt_le_adv_stop and bt_mesh_prov_disable didn't stop mesh advertisement, since calling bt_le_adv_start function after them returned EALREADY error code. As I think, I could merely set a flag to upgrade (after pressing a button or some command) and reboot microcontroller, and depending on this flag run the FOTA upgrade sample. But I think that there's a more straightforward way to realise this functionality. Can you explain to me how to merge BLE mesh example and FOTA upgrade properly?

  • Hi,

    Sorry for the late reply. I spoke to one of our developers about this and it seems like this isn't supported, unfortunately.

  • Thanks for your reply! It sounds frustrating.

    But is it possible to stop BLE mesh advertising and run ordinary BLE advertising by some trigger kinda a button or a command? Do you want to say that it's impossible to realise? Why doesn't bt_mesh_prov_disable function stop BLE mesh to allow me to run bt_le_adv_start after it and advertise SMP Service with UUID 8D53DC1D-1DB7-4CD3-868B-8A527460AA84 and etc.? And is it an appropriate workaround to reboot the microcontroller with running BLE mesh and run usual FOTA upgrade after it without BLE mesh? It won't be FOTA upgrade through BLE mesh, certainly, rather it will be direct BLE connection and upgrade.

    I merely thought that others realised the same functionality and it's a typical problem, which already was solved. That's why I would like to know the best practice how to realise FOTA upgrade in the case of BLE mesh.

    How is it expected to realise FOTA upgrade of microcontrollers within a BLE mesh?

  • Hi,

    Sorry for the confusion, it was a misuderstanding of the question.

    Yes, It is possible to realise both BLE Mesh and FOTA. You can disable the mesh stack, and start your own BLE operations for a time period to do this.

    RAlexeev said:
    Why doesn't bt_mesh_prov_disable function stop BLE mesh to allow me to run bt_le_adv_start after it and advertise SMP Service with UUID 8D53DC1D-1DB7-4CD3-868B-8A527460AA84 and etc.?

    I'm not sure why it doesn't disable the mesh. Have you debgged the code and see if the are any error messages retrning when you call bt_mesh_prov_disable? 

    RAlexeev said:
    And is it an appropriate workaround to reboot the microcontroller with running BLE mesh and run usual FOTA upgrade after it without BLE mesh?

    Yes, it this should be fine doing this.

  • Thanks for your answers.

    Yes, it this should be fine doing this.

    It's great, but I consider it as the last option, because it's not a pretty elegant solution.

    Yes, It is possible to realise both BLE Mesh and FOTA. You can disable the mesh stack, and start your own BLE operations for a time period to do this.

    Great! However, I faced some errors and it didn't work properly. In the case of unprovisioned node, I merely don't understand why bt_mesh_prov_disable() returns success and at the same time in debug log I see an error "bt_mesh_proxy: Failed to stop advertising (err -5)". But in the case, if a node is provisioned, then I can't disable BLE mesh and advertise SMP Service at all.

    As an example, if I modify your example Bluetooth: Mesh Light, adding a feature of disabling provisioning bearers and stopping advertisements after bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT) kinda like this:

    err = bt_mesh_prov_disable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
    if (err) {
        LOG_ERR("Failed to disable \"BT_MESH_PROV_ADV | BT_MESH_PROV_GATT\" (err %d)", err);
        return;
    } else {
        LOG_INF("\"BT_MESH_PROV_ADV | BT_MESH_PROV_GATT\" disabled");
    }
    
    err = bt_le_adv_stop();
    if (err) {
        LOG_ERR("Failed to stop advertising (err %d)", err);
    } else {
        LOG_INF("Stop advertising");
    }

    then bt_mesh_prov_disable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT) and bt_le_adv_stop() return successfully, but at the same time I have such warning and error in logs during calling those functions:

    [00:00:02.497,253] <wrn> bt_hci_core: opcode 0x200a status 0x0c
    [00:00:02.497,253] <err> bt_mesh_proxy: Failed to stop advertising (err -5)

    However, when I call these functions in the opposite order, firstly - bt_le_adv_stop(), and secondly - bt_mesh_prov_disable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT), then I don't have those warning and error in logs. Should I call bt_mesh_prov_disable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT) at all or not?

    But if I call just bt_le_adv_stop() without bt_mesh_prov_disable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT), then after calling bt_le_adv_start() nRF Connect for Mobile app shows "Mesh Provisioning Service". But if I call bt_mesh_prov_disable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT), then I don't have "Mesh Provisioning Service" in a list of services.

    Everything above was for the cases, when I didn't provision a node. In the case when I provisioned the node, and after it I tried to stop BLE mesh and start ordinary advertisement by calling these functions: bt_le_adv_stop() and bt_le_adv_start(), both of them return success result, but in reality the node doesn't start ordinary advertisement, and I see some grey records in nRF Connect for Mobile app with names "N/A (Bluetooth Mesh)" and multiple addresses. If I also call bt_mesh_prov_disable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT), then this function returns error code 69 regardless of it was called before or after bt_le_adv_stop().

    Thus, when the node is unprovisioned, then I can call bt_le_adv_stop() and bt_mesh_prov_disable() to stop a mesh and bt_le_adv_start() after it to start ordinary advertisement of SMP Service with UUID 8D53DC1D-1DB7-4CD3-868B-8A527460AA84. Is it the right way or not? It seems that it works. But what should I do in the case of the provisioned node? Tell me, please, how to start an ordinary advertisement, when the node is already provisioned? And is it enough to call bt_le_adv_stop() and bt_mesh_prov_disable() to disable BLE mesh or should I call something else also?

    I would be appreciated if you assist me in this issue before the weekends.

  • Hi,

    The problem might be that you are calling bt_mesh_prov_disable(), you should call bt_mesh_suspend() instead.

Related