This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to discover services only ones?

Hello,

I'm trying to store the discovered services and characteristics only ones at first connection with an bonded device at the central. So following connection events will be faster. Currently my code for the discovery looks like this:

    case DM_EVT_CONNECTION:
    {

					m_client.handle = (*p_handle);
									
					memset(&m_client.srv_db, 0 , sizeof (m_client.srv_db));
					
					// Discover peer's services. 
					err_code = ble_db_discovery_start(&m_client.srv_db,
																						p_event->event_param.p_gap_param->conn_handle);
					APP_ERROR_CHECK(err_code);							
					
        m_peer_count++;

        if (m_peer_count < MAX_PEER_COUNT)
        {
            scan_start();
        }
					
        break;
    }

Now I want to do something to not have to do ble_db_discovery_start at each connection.

I found that you can use these functions to do this:

ret_code_t dm_application_context_set(dm_handle_t const              * p_handle,
                                    dm_application_context_t const * p_context)

ret_code_t dm_application_context_get(dm_handle_t const        * p_handle,
                                    dm_application_context_t * p_context)

But how to actually do this is never explained.

Can anyone get me on the right track to implement this.

Thanks.

Parents
  • I mentioned here:

    In ble_app_hrs_c the Database Discovery module does service discovery to find the attribute handles for the CCCD and the characterisitic value for hrs and bas. To skip this step you need to store these (persistently or not) on the first connection and then give them to ble_hrs_c and ble_bas_c on subsequent connections.

    If you don't need to store them persistenly, you actually don't need to give the handles to ble_hrs_c and ble_bas_c on subsequent connections, because the handles will be in memory.

    The current flow in ble_app_hrs_c is like this.

    1. Application receives the DM_EVT_CONNECTION event through the device_manager_event_handler and calls ble_db_discovery_start().

    2. The database discovery module will send events to hrs and bas through db_discover_evt_handler(). If the heart rate service is found hrs will send the BLE_HRS_C_EVT_DISCOVERY_COMPLETE event to main where dm_security_setup_req() and ble_hrs_c_hrm_notif_enable() will be called, triggering bonding and enabling notifications respectively. If the battery service is found bas will send the BLE_BAS_C_EVT_DISCOVERY_COMPLETE event to main where ble_bas_c_bl_notif_enable() will be called.

    (3. When security setup is complete the DM_EVT_SECURITY_SETUP_COMPLETE event is received, which for some unknown reason calls ble_hrs_c_hrm_notif_enable() again.)

    There are probably many ways to solve this, but here is my suggestion.

    Add a flag which is set to true. This is checked in the DM_EVT_CONNECTION event. So service discovery will only be done if it is true. If it is false, dm_security_setup_req() will be called. The flag is set to false on the DM_EVT_SECURITY_SETUP_COMPLETE event.

    Now service discovery is only performed on first connection.

    We also need to make sure that notifications are enabled (CCCD = 0x0001) on the peripheral, so that it is able to send notifications. When you bond with the ble_app_hrs example it should actually store the CCCDs values, and restore them on reconnection. I tested this, and it worked fine the the heart rate service, but the battery service wouldn't send notifications. I'm not sure why, but I'll try to look into this some more when I have time.

    I wanted to call ble_hrs_c_hrm_notif_enable() and ble_bas_c_bl_notif_enable() when the DM_EVT_SECURITY_SETUP_COMPLETE event is received, since this will only be received once; when bonding procedure is complete. But as I mentioned then the battery service wouldn't send notifications this way.

    So instead I call them when the DM_EVT_LINK_SECURED event is received, which will be received on every reconnection (and the first connection). This approach results in two "unnecessary" write requests on reconnection, but this is what I have for now.

    I also commented out some function calls from hrs_c_evt_handler() and bas_c_evt_handler().

    Initial tests shows that it is working, but it is given as is.

    I have attached my project, I added pemy as a codeword all the places (I think) I have made changes.

    Peripheral side: \examples\ble_peripheral\ble_app_hrs, SDK 9.0.0, S110 8.0.0.

    Central side ble_app_hrs_c_cache, SDK 9.0.0, S120 2.1.0. Should be placed in \examples\ble_central

    Here is a sniffer trace. You can see on second connection the link gets encrypted, no service discovery, two write requests, and notifications are sent.

Reply Children
No Data
Related