Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Central and Peripheral: BLE_NUS in parallel with BLE_HRS_C

Hi, 

would like to run several (8) BLE_HRS_C in parallel to one BLE_NUS on a nRF5. Can that work?

In general, is it there any sample code showing how to implement peripheral role (BLE_NUS)  in parallel with central role (BLE_HRS_C)? 

The problem I am encountering (on nRF52840 DK, nRF5_SDK_15.2.0_9412b96) is with BLE_NUS, when sending data (ble_nus_data_send()) it hangs in ble_link_ctx_manager.c:70:

```

70 if (conn_id >= p_link_ctx_storage->max_links_cnt)

71 {
72 return NRF_ERROR_NO_MEM;
73 }

```

as the connection id of the peripheral (BLE_NUS) conn_id==8 and there is only 1 BLE_LINK_CTX_MANAGER_DEF defined (in ble_nus.c), therefore p_link_ctx_storage->max_links_cnt==1. What is the right way to solve this?

Thanks,

Andrea

  • Yes, sure. The below is sufficient. But I did not wanna modify SDK files. Just wondering what is the right way to do it. 

    diff --git a/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.c b/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.c
    index 2a139f4..11ae062 100644
    --- a/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.c
    +++ b/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.c
    @@ -67,10 +67,10 @@ ret_code_t blcm_link_ctx_get(blcm_link_ctx_storage_t const * const p_link_ctx_st
             return NRF_ERROR_NOT_FOUND;
         }
     
    -    if (conn_id >= p_link_ctx_storage->max_links_cnt)
    -    {
    -        return NRF_ERROR_NO_MEM;
    -    }
    +    //if (conn_id >= p_link_ctx_storage->max_links_cnt)^M
    +    //{^M
    +    //    return NRF_ERROR_NO_MEM;^M
    +    //}^M
     
         *pp_ctx_data = (void *) ((uint8_t *) p_link_ctx_storage->p_ctx_data_pool + 
                                  conn_id * p_link_ctx_storage->link_ctx_size);
    

  • With the current implementation, the more correct way would probably be to use the link context manager for all links and not just the NUS connection. But I think it's ok to modify the SDK module as you did.

  • This issue is a pain for me as well. Having central and peripheral connections doesn't work very well with the link ctx mgr. It's a bit wasteful having  sizeof(ble_nus_client_context_t) * num_central_connections unused bytes allocated for the ctx manager. Especially when you've got a lot of connection which use up a lot ofRAM already. 

    I know it's not ideal but I use my own blcm_link_ctx_get function to handle this

    static uint32_t get_link_ctx(ble_gm_device_t * p_gm_device, uint16_t conn_handle, ble_gm_device_client_context_t ** const p_client)
    {
        if (p_client == NULL)
        {
            return NRF_ERROR_NULL;
        }
        else
        {
            *p_client = NULL;
        }
        
        VERIFY_PARAM_NOT_NULL(p_gm_device->p_link_ctx_storage);
        VERIFY_PARAM_NOT_NULL(p_gm_device->p_link_ctx_storage->p_ctx_data_pool);
        VERIFY_TRUE((p_gm_device->p_link_ctx_storage->link_ctx_size % BYTES_PER_WORD) == 0, NRF_ERROR_INVALID_PARAM);
        
        uint16_t link_ctx_index = 0;
        for(link_ctx_index = 0; link_ctx_index < p_gm_device->p_link_ctx_storage->max_links_cnt; link_ctx_index++)
        {
            if(p_gm_device->conn_handles[link_ctx_index] == conn_handle )
            {
                *p_client = (void *) ((uint8_t *) p_gm_device->p_link_ctx_storage->p_ctx_data_pool + 
                                 link_ctx_index * p_gm_device->p_link_ctx_storage->link_ctx_size);
                return NRF_SUCCESS;
            }
        }
        return NRF_ERROR_NOT_FOUND;
        
    }

Related