This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
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

Problems with the db discovery module

Hi everybody.

I am opening a dedicate question after a recent topic that already helped me a lot, with another discussion pretty similar to my problem. Resuming briefly, i have two nordic devices, a smart beacon kit (SDK 7.1 with s110) that is sending temperature by notification with a custom service (from service tutorial here on the nordic site), and a DK (SDK 11 with s130) that must receive the values and send it via USB to the PC. I use the ble_app_uart_c as reference on the DK, modified by one of the moderators to find the UUID of my service on the beacon and connect to it (function is_uuid_present), and this works correctly. The problem is that the next step should be find the service on the beacon with the discovery module, in order to start the transmission of the values, but it seems that the discovery module doesn't find the service (it starts correctly, but the function db_disc_handler, which should be called when a discovery event occurs, never executes). I load the two projects (the one on the beacon that i think at this point should be ok, and the one on the DK), can you please help me understand the error, or if i am using correctly the discovery module? Probably is some kind of stupid error caused by my inexperience ^^' Thanks in advance!

Or at least please tell me how should i use correctly the db discovery module, in terms of what field i should fill to make it find my service and characteristic or what esle!

projects.zip

libraries.zip

Parents
  • Hi,

    I think maybe I have figured it out. The reason why it was hard to debug was that you and I have been using different ble_nus_c.c files (since this file is not placed in the project folder). You have modified yours, but I have been using the original. When I tried the one you have uploaded I see the same behaviour as you.

    It is not a regular disconnect you see, but a complete system reset. You suspected that something goes wrong in db_disc_handler(), right? This function calls ble_nus_c_on_db_disc_evt() and that is a function written specifically for the NUS service. The original function has the following if-statement inside it:

    if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
        p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_NUS_SERVICE &&
        p_evt->params.discovered_db.srv_uuid.type == p_ble_nus_c->uuid_type)
        {
            ....
    

    If the original code is used with your beacon this if-statement will always be false because the beacon does not contain the BLE_UUID_NUS_SERVICE. This will "jump over" the code causing your problems. The code will continue to run, but not work as intended. Note that the if-statement will also be false if you change BLE_UUID_NUS_SERVICE to a random value, like 2, as you describe in your comment.

    So I believe the problem is that you have changed the if statement to:

    if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
        p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_OUR_SERVICE &&
        p_evt->params.discovered_db.srv_uuid.type == p_ble_nus_c->uuid_type)
        {
            ....
    

    where BLE_UUID_OUR_SERVICE is a service UUID found on the beacon. However, you have forgotten to change BLE_UUID_NUS_RX_CHARACTERISTIC to BLE_UUID_OUR_CHARACTERISTC_UUID. Because you forgot that the CCCD handle is never updated. This causes ble_nus_c_rx_notif_enable() in ble_nus_c_evt_handler() to fail and return an error code. If you have not followed my advice in the comments about looking for asserts the result is that your code will reset over and over again and never work. If you did follow my advice you should have seen that the code asserts after ble_nus_c_rx_notif_enable(). Inside the function you will find the reason:

    if ( (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID)
       ||(p_ble_nus_c->handles.nus_rx_cccd_handle == BLE_GATT_HANDLE_INVALID)
       )
        {
            return NRF_ERROR_INVALID_STATE;
        }
    

    If you don't update the CCCD value this if-statement will return true and NRF_ERROR_INVALID_STATE is returned.

    If I use your files and just change BLE_UUID_NUS_RX_CHARACTERISTIC to BLE_UUID_OUR_CHARACTERISTC_UUID the code seems to work fine and I get periodic notifications and "Eureka"s.

Reply
  • Hi,

    I think maybe I have figured it out. The reason why it was hard to debug was that you and I have been using different ble_nus_c.c files (since this file is not placed in the project folder). You have modified yours, but I have been using the original. When I tried the one you have uploaded I see the same behaviour as you.

    It is not a regular disconnect you see, but a complete system reset. You suspected that something goes wrong in db_disc_handler(), right? This function calls ble_nus_c_on_db_disc_evt() and that is a function written specifically for the NUS service. The original function has the following if-statement inside it:

    if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
        p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_NUS_SERVICE &&
        p_evt->params.discovered_db.srv_uuid.type == p_ble_nus_c->uuid_type)
        {
            ....
    

    If the original code is used with your beacon this if-statement will always be false because the beacon does not contain the BLE_UUID_NUS_SERVICE. This will "jump over" the code causing your problems. The code will continue to run, but not work as intended. Note that the if-statement will also be false if you change BLE_UUID_NUS_SERVICE to a random value, like 2, as you describe in your comment.

    So I believe the problem is that you have changed the if statement to:

    if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
        p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_OUR_SERVICE &&
        p_evt->params.discovered_db.srv_uuid.type == p_ble_nus_c->uuid_type)
        {
            ....
    

    where BLE_UUID_OUR_SERVICE is a service UUID found on the beacon. However, you have forgotten to change BLE_UUID_NUS_RX_CHARACTERISTIC to BLE_UUID_OUR_CHARACTERISTC_UUID. Because you forgot that the CCCD handle is never updated. This causes ble_nus_c_rx_notif_enable() in ble_nus_c_evt_handler() to fail and return an error code. If you have not followed my advice in the comments about looking for asserts the result is that your code will reset over and over again and never work. If you did follow my advice you should have seen that the code asserts after ble_nus_c_rx_notif_enable(). Inside the function you will find the reason:

    if ( (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID)
       ||(p_ble_nus_c->handles.nus_rx_cccd_handle == BLE_GATT_HANDLE_INVALID)
       )
        {
            return NRF_ERROR_INVALID_STATE;
        }
    

    If you don't update the CCCD value this if-statement will return true and NRF_ERROR_INVALID_STATE is returned.

    If I use your files and just change BLE_UUID_NUS_RX_CHARACTERISTIC to BLE_UUID_OUR_CHARACTERISTC_UUID the code seems to work fine and I get periodic notifications and "Eureka"s.

Children
Related