Bluetooth mesh configuration failure

board: nrf52832

nRF5 SDK version: v17.0.0

nRF5 SDK for Mesh version: v5.0.0

softdevice: S332

application: light switch client + light switch server + provisioner + ble_ant_app_hrm + ble_app_uart_coexist

My application have two characters to choose: Provisioner/self provisioned Client and Server, user can send UART command to select one of them to initialize on device,

and I delete normal BLE  (NUS service)

The problem is, when I set one device as Provisioner/self provisioned Client, and two devices as Server,

the first Server would be provisioned and configured successfully, and the provision of second Server would success, but the configuration of second Server failed occasionally

But, if I turn the first Server off before the provision process of second Server start, the provision and configuration of the second Server would all success

(Once Provisioner/self provisioned Client detect one unprovision Server, ANT+ channel will close automatically)

So I check configuration process, and found it often stuck in receiving opcode CONFIG_OPCODE_MODEL_APP_STATUS or CONFIG_OPCODE_APPKEY_STATUS, although Server receive opcode CONFIG_OPCODE_MODEL_APP_BIND or CONFIG_OPCODE_APPKEY_ADD and reply successfully (return NRF_SUCCESS),

but Provisioner/self provisioned Client didn't receive this reply, although Provisioner/self provisioned Client retry send APP_ADDKEY and wait for an ACK from Server for 2-3 times,

this situation keeps occur

Log:

Provisioner/Client print config_step_execute() in node_setup.c to check what opcode it receive (the value after ":" is the status of message)

Server print send_reply() in config_server.c to check the status of transmission and what opcode it send  (the first value is return value of send_reply(), the second value is opcode id it send)

  • the process of configuration of the first Server (success)        Provisioner/Client                                                                   the first Server                                                               

                          

  • the process of configuration of the second Server (fail)

                    Provisioner/Client                                                                                                     the second Server

                         

 

Then I check  function scanner_rx() in scanner.c of Provisioner/self provisioned Client, filter MAC address of the second Server to see if Provisioner/self provisioned Client receive messages from the second Server, I found Provisioner/self provisioned Client keeps receive messages of the second Server like below 

  • Provisioner/Client:

            one "Get" means get one message from the second Server ( recognized by MAC address) ( scanner_rx() in scanner.c)

            "receive opcode: (mesh_msg_handle() in access.c)            

            

  • the second Server

             "receive opcode: (mesh_msg_handle() in access.c)   

             "access_model_reply()" (send_reply() in config_server.c)             

            

  • the first Server:have been provisioned and configured, help me to print the payload of the second Server ( recognized by MAC address), 1-31 bytes are payload, the last byte is header type, '#' is the end of line  ( scanner_rx() in scanner.c)

            

it seems like Provisioner/self provisioned Client can receive messages from the second Server but the ACK of Configuration, it confuses me, is there any way to analyze the payload from the second Server?  or Is there any chance that the ACK message of Configuration is filtered out by application of Provisioner/Client?

BTW, if all devices have been provisioned and configured, the communication of two characters works well,

and I have tried increase advertising interval to 100 ms and this (change SCANNER_BUFFER_SIZE to 1024), but it didn't work to me.

  • Hey Erin!

    Just letting you know that I am looking into it, but I will have to get back to you.

    Best regards,

    Elfving

  • Hey again Erin!

    Could you fix the error log images? Several of them didn't seem to get uploaded.

    Best regards,

    Elfving

  • Hey Erin!

    Sorry this is taking so long. I have been asking internally about this, and our mesh team has been a bit busy lately.

    An ACK message getting filtered out doesn't seem like the most likely scenario to me. I would rather think that there is an issue with the provisioner+client node, or that the extra node leads to package collisions or that the message fails to arrive due to other reasons. 

    Could you try increasing the retransmit count? It is 0 by default. If this doesn't help we should take a closer look at the provisioner+client. 

    Best regards,

    Elfving

  • Hi Elfving,
    Thank you for your reply, I've try increace the CONFIG_RETRANSMIT_COUNT_MAX (/models/foundation/config/include/config_messages.h), but it still fail ocasionally..

    To simplify this issue, I restart from downloading the SDK, and migrate example projects again.

    Version (Migration):
    PC: ubunrtu 16.04
    board: nrf52832
    nRF5 SDK version: nRF5_SDK_17.1.0_ddde560
    nRF5 SDK for Mesh version: v5.0.0
    softdevice: S332
    toolchain: armgcc

    The steps of example projects migration:
    [ ble_ant_app_hrm + sdk_coexist(light switch client) ] ===> clients (migration ver.)
    step 1. mesh SDK merge into nRF SDK
    step 2. /examples/sdk_coexist/ble_app_uart_coexist/pca10040/s132/config/sdk_config.h merge into /examples/multiprotocol/ble_ant_app_hrm/pca10040/s332/config/sdk_config.h
    step 3. nrf_mesh.h and hal.c add "definedS332"
    step 4. combain main.c of ble_ant_app_hrm + sdk_coexist
    step 5. makefile add relative .c .h CFLAGS
    step 6. create a folder "include", put /examples/sdk_coexist/ble_app_uart_coexist/nrf_mesh_config_app.h into it
    step 7. put /examples/sdk_coexist/ble_app_uart_coexist/mesh_main.h and /examples/sdk_coexist/ble_app_uart_coexist/mesh_main.c into project folder
    step 8. nrf_mesh_config_app.h add #define GENERIC_DTT_SERVER_INSTANCES_MAX (1), #define GENERIC_ONOFF_SERVER_INSTANCES_MAX (1) and #define SCENE_SETUP_SERVER_INSTANCES_MAX (0)
    step 9. put /examples/light_switch/server/include/app_config.h into "include" folder of project
    step 10. #define APP_TIMER_CONFIG_RTC_FREQUENCY 0, #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 69 (in sdk_config.h)
    step 11. #define NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 2400, #define NRF_SDH_BLE_VS_UUID_COUNT 1 (in sdk_config.h)
    step 12. RAM (rwx):ORIGIN=0x20002968, LENGTH=0xD698 (in ble_ant_hrm_gcc_nrf52.ld)
    step 13. add .nrf_mesh_ram and .nrf_mesh_flash (in ble_ant_hrm_gcc_nrf52.ld)
    step 14. #define ACCESS_ELEMENT_COUNT (2) (in nrf_mesh_config_app.h)
    step 15. coment out ANT+ channel open (in main.c)

    [ ble_ant_app_hrm + sdk_coexist(light switch client) + light switch server ] ===> server (migration ver.)
    step 1. base on clients (migration ver.), replace the content of mesh_main.c to the content of /examples/light_switch/server/main.c
    step 2. delete useless funtion and change function name which depands on mesh_main.h (mesh_main.c)

    [ ble_ant_app_hrm + sdk_coexist(light switch client) + provisioner ]
    step 1. put /examples/provisioner/src/node_setup.c and /examples/provisioner/src/provisioner_helper.c into project folder
    step 2. put all file in /examples/provisioner/include into "include folder of project folder, except app_config.h and nrf_mesh_config_app.h
    step 3. #define MODEL_ACKNOWLEDGED_TRANSACTION_TIMEOUT (SEC_TO_US(10)), #define ACCESS_DEFAULT_TTL (MAX_PROVISIONEE_NUMBER > NRF_MESH_TTL_MAX ? NRF_MESH_TTL_MAX : MAX_PROVISIONEE_NUMBER) (nrf_mesh_config_app.h)
    step 4. #define ACCESS_MODEL_COUNT(4) (nrf_mesh_config_app.h)
    step 5. #define CONFIG_SCENARIO_COMMON delete NODE_SETUP_CONFIG_APPKEY_BIND_HEALTH and NODE_SETUP_CONFIG_PUBLICATION_HEALTH (config_scenarios.h)
    step 6. #define CONFIG_SCENARIO_COMMON delete NODE_SETUP_CONFIG_APPKEY_BIND_HEALTH and NODE_SETUP_CONFIG_PUBLICATION_HEALTH (config_scenarios.h)
    step 7. #define CONFIG_SCENARIO_LIGHT_SWITCH_CLIENT_EXAMPLE delete the second CONFIG_ONOFF_CLIENT (config_scenarios.h)
    step 8. #define CONFIG_SCENARIO_LIGHT_SWITCH_SERVER_EXAMPLE delete the second CONFIG_ONOFF_SERVER (config_scenarios.h)
    step 9. #define APP_TIMER_KEEPS_RTC_ACTIVE 1 (in sdk_config.h)
    step 10. makefile add relative .c
    step 11. /examples/provisioner/src/main.c merge into mesh_main.c
    step 12. #define DSM_SUBNET_MAX(20), #define DSM_APP_MAX(35), #define DSM_DEVICE_MAX(35), #define DSM_VIRTUAL_ADDR_MAX(15), #define DSM_NONVIRTUAL_ADDR_MAX(15) (nrf_mesh_config_app.h)

    [ ble_ant_app_hrm + sdk_coexist(light switch client) + provisioner(light switch client self provision) ] ===> Provisioner/Client (migration ver.)
    step 1. in struct network_dsm_handles_data_volatile_t, replace health instance to generic_onoff_client_t client_instance (network_setup_types.h)
    step 2. app_default_models_bind_setup() add publish and subscription setting of light switch client (mesh_main.c)
    step 3. models_init_cb() add calback function setting of light switch client (mesh_main.c)
    step 4. mesh_main_button_event_handler() add message publish function of light switch client (mesh_main.c)
    step 5. coment out all normal BLE service (main.c)

    When use the Provisioner/Client (migration ver.) to provision and configure two devices, these situations would happen:
    (1)provision and configure two servers (migration ver.), configuration data transmition retry many times ===> might okay, but the process of the second server take time and fail ocasionally
    (2)after the second server (migration ver.) had provisioned and configured, the second server (migration ver.) delete provision and configuration and Provisioner/Client (migration ver.) immediately ===> might okay, and the process of provision and configuration will implement smoothly but fail ocasionally
    (3)provision and configure two clients (migration ver.) ===> totally ok, even the second client would be provisioned and configured smoothly
    (4)provision and configure two servers (migration ver.), and trun the first server off ===> totally ok

    And I also use the Provisioner/Client (migration ver.) to provision and configure the light switch example form Mesh SDK
    Version (light switch example form Mesh SDK):
    PC: ubunrtu 20.04
    board: nrf52832
    nRF5 SDK version: nRF5_SDK_17.0.2_d674dde
    nRF5 SDK for Mesh version: v5.0.0
    softdevice: S332
    toolchain: armgcc

    (5)provision and configure two servers (example form Mesh SDK ver.) ===> totally ok, even the second server would be provisioned and configured smoothly

    So, it seems like provisioner/client is work normally, but the server(migration ver.) have some unknow issue.
    Are there any configurations I didn't set? or do you have any suggestions for me to try?

    The archive file below is my Client (migration ver.), server (migration ver.), Provisioner/Client (migration ver.) project, hope it helps!

    4643.nordic_devzone_mesh_bluetooth_mesh_configuration_failure.zip

    Regards,
    Erin

Related