about conn_handle maintain

nRF5_SDK_17.1.0

PCA10059

For I want to provide up to 20 central connections, I have defined the objects like this( inherited from example code):

GATEWAY_ARRAY_DEF(  
										m_gateway_array, 
										NRF_SDH_BLE_CENTRAL_LINK_COUNT);                    //< TGOI client instances. 

BLE_DB_DISCOVERY_ARRAY_DEF(
										m_db_disc_array, 
										NRF_SDH_BLE_CENTRAL_LINK_COUNT);                    //< Database discovery module instances. 

NRF_BLE_GQ_DEF(m_ble_gatt_queue,                                        //< BLE GATT Queue instance. 
               NRF_SDH_BLE_CENTRAL_LINK_COUNT,
               NRF_BLE_GQ_QUEUE_SIZE);


NRF_BLE_GATT_DEF(m_gatt);                                               //< GATT module instance. 

NRF_BLE_SCAN_DEF(m_scan);                                               //< Scanning Module instance. 

The conn_handle is the index to access arrays,that means for conn_handle ch,it's gateway instance is m_gateway_array[ch],it's discovery instance is m_db_disc_array[ch],and it's gatt queue is m_ble_gatt_queue[ch]. conn_handle is the primary key to access all object related to the connection defined by conn_handle.

And it is maintained by SD.

My question is : if one connection(conn_handle_A) broken(power off e.g.),and next BLE peripheral trying to connect after that,will SD allocate which conn_handle to this peripheral?

The reason to ask is may there are data left in m_ble_gatt_queue[conn_handle_A],I have to make choice on those data.

If the origal peripheral connected again with the same conn_handle,I can transfer those data to it again.

If a different peripheral connected with this conn_handle, wrong data will send to it .

I have to do some check work to clarify if the data left in queue belong to current instance or not.

That will be helpful if I can get some explaination on conn_handle.

Thank you.

Parents
  • Hi MengChang, 

    As far as I know the softdevice does recycle the conn_handle. However,the challenge here is that you are not guarantee that your peripheral will have only one conn_handle at a time. There is a chance that a device get disconnected and start advertising, but the central is still waiting for the timeout and a new connection maybe established before the old connection terminated. In this situation, a peripheral will appear in 2 connections. If you don't have a good solution for this situation you will have your data being locked in the queue. 


    My suggestion is to use the address/IRK as the index and only use that index to handle the data. You will need to have an extra buffer to store the data instead of keeping them in the gatt queue.
    When a connection terminated you would need to backup the data in the queue to the main buffer, then discard it in the queue. After that wait for the peripheral to reconnect to feed the data to the queue again. 

  • Thank you for reply.

    I really did not think of 2 connections issue:)

    Your solution should work.

    The backup buffer can serve whole arrays.

    What I thought before is to use peripheral ID(address as you said?) as a identity:

    1) define a characteristic to provide ID in BLE peripheral;

    2) central read the ID and store it in m_gateway;

    3) compare the ID from peripheral & m_gateway in discovery event.

    I don't know if that will work.

    But,first of all, we'd better know how SD deal with conn_handle.

  • HI MengChang, 

    I think it would work. But you will have to add one extra ID as you mentioned. 

    Another option, if your central is bonded with the peripheral is to use the peer manager and check if the device is re-connected to a bonded peer. You can catch this event PM_EVT_BONDED_PEER_CONNECTED in your pm_evt_handler() in main.c . p_pm_evt->peer_id will show which peer_id is connected. 

  • I can't bond the peripheral to central device.

    Maybe there are more than 1 central device,I name them gateway.The peripherals will randomly connect to one of the gateway,it will still randomly select one gateway to connect after broken connection, so there are no perfect way to solve this problem, just do it better,I will code as your advice: add ID,add extra-buffer.

    Thank you.

  • Hello,Bui:

    I looked through the code in nrf_ble_gq.c:

    void nrf_ble_gq_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
    {
        nrf_ble_gq_t * p_gatt_queue = (nrf_ble_gq_t *) p_context;
        uint16_t       conn_handle;
        uint16_t       conn_id;
    
        if ((p_ble_evt == NULL) || (p_gatt_queue == NULL))
        {
            return;
        }
    
        // Obtain connection handle and filter out the events that do not trigger queue processing.
        if (p_ble_evt->header.evt_id == BLE_GAP_EVT_DISCONNECTED)
        {
            conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
        }
        else if ((p_ble_evt->header.evt_id >= BLE_GATTC_EVT_BASE) &&
                 (p_ble_evt->header.evt_id <= BLE_GATTC_EVT_LAST))
        {
            conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
        }
        else if ((p_ble_evt->header.evt_id >= BLE_GATTS_EVT_BASE) &&
                 (p_ble_evt->header.evt_id <= BLE_GATTS_EVT_LAST))
        {
            conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
        }
        else
        {
            // These events are irrelevant for this module.
            return;
        }
    
        // Check if connection handle is registered.
        conn_id = conn_handle_id_find(p_gatt_queue, conn_handle);
        if (conn_id == p_gatt_queue->max_conns)
        {
            return;
        }
    
        // Perform operations on the queue.
        if (p_ble_evt->header.evt_id == BLE_GAP_EVT_DISCONNECTED)
        {
            p_gatt_queue->p_conn_handles[conn_id] = BLE_CONN_HANDLE_INVALID;
            UNUSED_RETURN_VALUE(nrf_queue_push(p_gatt_queue->p_purge_queue, &conn_id));
        }
        else
        {
            queue_process(&p_gatt_queue->p_req_queue[conn_id], conn_handle);
        }
    }

    It looks like BLE GQ will clear the data first(?)

    If so, the application code can't backup the data. 

  • Hi MengChang, 
    I think you are right. I think it makes sense to clear the buffer when the connection is terminated.

    If you want to change this behavior you would need to modify the gq library to back up the data before the clear. 

Reply Children
No Data
Related