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);
?