Hi Nordic,
I am currently looking at using the link context manager introduced in SDK15.0 . I can see it could be useful for my application where each connection needs a different value.
The context manager allocates a block of memory for each context whose size is based on the number of clients and the ssize of each context
However, I can see a potential issue with using the connection
/**@brief Macro for defining a blcm_link_ctx_storage instance.
*
* @param[in] _name Name of the instance.
* @param[in] _max_clients Maximum number of clients connected at a time.
* @param[in] _link_ctx_size Context size in bytes for a single link.
*/
#define BLE_LINK_CTX_MANAGER_DEF(_name, _max_clients, _link_ctx_size) \
STATIC_ASSERT((_max_clients) < BLE_CONN_STATE_MAX_CONNECTIONS); \
static uint32_t CONCAT_2(_name, _ctx_data_pool)[(_max_clients)*BYTES_TO_WORDS(_link_ctx_size)]; \
static blcm_link_ctx_storage_t _name = \
{ \
.p_ctx_data_pool = CONCAT_2(_name, _ctx_data_pool), \
.max_links_cnt = (_max_clients), \
.link_ctx_size = sizeof(CONCAT_2(_name, _ctx_data_pool))/(_max_clients) \
}
and uses the connection handle as an index into that blck of memory
ret_code_t blcm_link_ctx_get(blcm_link_ctx_storage_t const * const p_link_ctx_storage,
uint16_t const conn_handle,
void ** const pp_ctx_data)
{
uint8_t conn_id;
if (pp_ctx_data == NULL)
{
return NRF_ERROR_NULL;
}
else
{
*pp_ctx_data = NULL;
}
VERIFY_PARAM_NOT_NULL(p_link_ctx_storage);
VERIFY_PARAM_NOT_NULL(p_link_ctx_storage->p_ctx_data_pool);
VERIFY_TRUE((p_link_ctx_storage->link_ctx_size % BYTES_PER_WORD) == 0, NRF_ERROR_INVALID_PARAM);
conn_id = ble_conn_state_conn_idx(conn_handle);
if (conn_id == BLE_CONN_STATE_MAX_CONNECTIONS)
{
return NRF_ERROR_NOT_FOUND;
}
if (conn_id >= p_link_ctx_storage->max_links_cnt)
{
return NRF_ERROR_NO_MEM;
}
*pp_ctx_data = (void *) ((uint8_t *) p_link_ctx_storage->p_ctx_data_pool +
conn_id * p_link_ctx_storage->link_ctx_size);
return NRF_SUCCESS;
}
But what happens if my device is acting as a cental and peripheral? Currently it looks like _max_clients
must be equal to the number of central + peripheral connections because the connection handle could be somewhere between 0 and the number of central + peripheral connections. It seems pretty wasteful to allocate space for these extra connections, which will never be used.
For example, I have an application where i have 8 central connections and 5 peripheral connections.
The peripheral services are service1 and service2
The central services are service3, service4, and service5
This means that for each service I need to allocate space for 13 instances. Because the conn handles for my peripheral and central connections can range between 0 and 12.
Could this be improved by using the ble_conn_state_central_conn_count() and ble_conn_state_peripheral_conn_count() functions as indexes instead? You would need to know whether its a client or server
Also, line 71 in ble_link_ctx_manager.h is
STATIC_ASSERT((_max_clients) < BLE_CONN_STATE_MAX_CONNECTIONS);
should this be
STATIC_ASSERT((_max_clients) <= BLE_CONN_STATE_MAX_CONNECTIONS);
?