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

custom service discovery in BLE_Central

Hi,

I want to develop central code to discover services of 3rd party device and to discover their services and read/write characteristics.

As seen many examples from SDK below is my understanding:

1. Include db_discovery_init() 

2. call ble_db_discovery_start() on BLE_GAP_EVT_CONNECTED event in ble_evt_handler().

3. While initlaizing need to init service which is going to discover as below:

like in BLE_blinky example,includes ble_lbs service as below :


static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
{
    ble_lbs_on_db_disc_evt(&m_ble_lbs_c, p_evt);
}

So my question is:

While db_discovery_init() which service should initialize in db_disc_handler() for custom service discovery? when we don't know which service is advertising by other device.

And

How to discover the services and print this and its characteristics on console. Same as we can see in nrf Connect app. Please suggest or share suitable code except BLE_UART example code.

Please help me on this asap.

Regards,

Prajakta

Parents
  • Hi Prajakta, 

    The db_disc_handler() is where you handle the events from the db discovery library, for example when the discovery is complete, or when the service is not found. 

    However, the db discovery module was not really made for generic service discovery. This means usually you need to provide the service UUID(s) you want to discover to the module before it started. 

    To be able to do generic discovery (where you discovery all UUIDs) you would need to modify it a little bit. There is some discussion here. Please have a look and let me know if you have any question. 

  • I am using BLE_Blinky application, in that after connection done, in ble_evt_handler (),handle_assign function is there, then they called ble_db_discovery_start.

    As per this discussion, need to call sd_ble_gattc_primary_services_discover.
    1.So where I can call this function with parameters?

    And

    2. Can you help me for flow for service discovery from start(init) to end in example code.I am able to do it for ble_lbs_c service(blinky application). I am not getting how to replicate it for primary service discovery.

  • getting start handle and end handle = 0 for last unknown service.

    So not able to get discover its characteristics.

    You can check code and output in above reply.
    Please let me know hot recover it.

  • Please make sure you check the status of the BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP  event and it's SUCCESS not ATTRIBUTE_NOT_FOUND 

  • While checking service count in return argument is gives count=3. As services shown under that are total 4

  • Then you need to continue calling sd_ble_gattc_primary_services_discover () until you receive ATTRIBUTE_NOT_FOUND  in the event BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP  

  • I am able to discover all services.

    I want to discover its characteristics and properties.

    As you said i have added sd_ble_gattc_primary_services_discover (), and after that calling characteristics discover()  function but it fails. I think conn_hdle is same for both functions so this issue is coming. 
    I am attaching code here.

    1.Can you help to discover services along with its characteristics?

    2. How to discover and print 128-bit UUID of unknown service.

    Code as below:

    void on_primary_srv_discovery_rsp(ble_db_discovery_t       * p_db_discovery,
                                             ble_gattc_evt_t    const * p_ble_gattc_evt)
    {
        ble_gatt_db_srv_t * p_srv_being_discovered;
        uint16_t count = 0;
    
        uint16_t        bytes_to_copy;
        static uint16_t offset = 0;
        int conn_hdle;
    	conn_hdle = p_ble_gattc_evt->conn_handle;
    
    
        ble_gattc_service_t * const p_service =
                		mp_device_srv[conn_hdle]->services;
    
        p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
    
        if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
        {
       // 	return;
        }
    
        if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
        {
    
        	//int i = 0;
        	ble_gattc_evt_prim_srvc_disc_rsp_t const * p_prim_srvc_disc_rsp_evt;
            uint32_t err_code;
    
            p_prim_srvc_disc_rsp_evt = &(p_ble_gattc_evt->params.prim_srvc_disc_rsp);
            count = p_prim_srvc_disc_rsp_evt->count;
            NRF_LOG_INFO("service count %d",count);
    
    		// If no more services are found.
    		if ((count != 0) &&
    		(p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS))
    		{
    			if ((count + offset) > MAX_SERVICE_COUNT)
    			{
    				bytes_to_copy = MAX_SERVICE_COUNT - offset;
    			}
    			else
    			{
    				bytes_to_copy = count;
    			}
    
    			// Save services data.
    			memcpy((p_service + offset),p_prim_srvc_disc_rsp_evt->services,
    			bytes_to_copy * sizeof(ble_gattc_service_t));
    
    			offset += count;
    			for(int i= 0;i <= count; i++ )
    			{
    			p_srv_being_discovered->srv_uuid     = p_prim_srvc_disc_rsp_evt->services[i].uuid;
    			p_srv_being_discovered->handle_range = p_prim_srvc_disc_rsp_evt->services[i].handle_range;
    
    			NRF_LOG_INFO("Found service UUID %x and its start handle:%d , End handle: %d", p_srv_being_discovered->srv_uuid.uuid,
    			p_srv_being_discovered->handle_range.start_handle, p_srv_being_discovered->handle_range.end_handle);
    			}
    			// If the last service has not been reached, this function must be called again with a new start handle.
    			err_code = sd_ble_gattc_primary_services_discover(conn_hdle,
    			p_prim_srvc_disc_rsp_evt->services[count - 1].handle_range.end_handle + 1,
    			NULL);
    			if(err_code == NRF_SUCCESS)
    			{
    			NRF_LOG_INFO("Discovery done successfully..");
    			}
    			else
    			{
    			NRF_LOG_INFO("Discovery Fail..");
    
    			}
    		//  APP_ERROR_CHECK(err_code);
    		}
    
            err_code = characteristics_discover(p_db_discovery, p_ble_gattc_evt->conn_handle);
    
            if (err_code != NRF_SUCCESS)
            {
                p_db_discovery->discovery_in_progress = false;
    
                NRF_LOG_INFO("Error with discovering the characteristics");
                // Indicate the error to the registered user application.
                discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle);
    
                m_pending_user_evts[0].evt.evt_type    = BLE_DB_DISCOVERY_AVAILABLE;
                m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
            }
        }
        else
        {
            NRF_LOG_INFO("Service UUID 0x%x not found.", p_srv_being_discovered->srv_uuid.uuid);
            // Trigger Service Not Found event to the application.
            discovery_complete_evt_trigger(p_db_discovery, false, p_ble_gattc_evt->conn_handle);
            on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle);
        }
        NRF_LOG_INFO("Services count at end: %d", offset);
         offset = 0;
    }
    

Reply
  • I am able to discover all services.

    I want to discover its characteristics and properties.

    As you said i have added sd_ble_gattc_primary_services_discover (), and after that calling characteristics discover()  function but it fails. I think conn_hdle is same for both functions so this issue is coming. 
    I am attaching code here.

    1.Can you help to discover services along with its characteristics?

    2. How to discover and print 128-bit UUID of unknown service.

    Code as below:

    void on_primary_srv_discovery_rsp(ble_db_discovery_t       * p_db_discovery,
                                             ble_gattc_evt_t    const * p_ble_gattc_evt)
    {
        ble_gatt_db_srv_t * p_srv_being_discovered;
        uint16_t count = 0;
    
        uint16_t        bytes_to_copy;
        static uint16_t offset = 0;
        int conn_hdle;
    	conn_hdle = p_ble_gattc_evt->conn_handle;
    
    
        ble_gattc_service_t * const p_service =
                		mp_device_srv[conn_hdle]->services;
    
        p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
    
        if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
        {
       // 	return;
        }
    
        if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
        {
    
        	//int i = 0;
        	ble_gattc_evt_prim_srvc_disc_rsp_t const * p_prim_srvc_disc_rsp_evt;
            uint32_t err_code;
    
            p_prim_srvc_disc_rsp_evt = &(p_ble_gattc_evt->params.prim_srvc_disc_rsp);
            count = p_prim_srvc_disc_rsp_evt->count;
            NRF_LOG_INFO("service count %d",count);
    
    		// If no more services are found.
    		if ((count != 0) &&
    		(p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS))
    		{
    			if ((count + offset) > MAX_SERVICE_COUNT)
    			{
    				bytes_to_copy = MAX_SERVICE_COUNT - offset;
    			}
    			else
    			{
    				bytes_to_copy = count;
    			}
    
    			// Save services data.
    			memcpy((p_service + offset),p_prim_srvc_disc_rsp_evt->services,
    			bytes_to_copy * sizeof(ble_gattc_service_t));
    
    			offset += count;
    			for(int i= 0;i <= count; i++ )
    			{
    			p_srv_being_discovered->srv_uuid     = p_prim_srvc_disc_rsp_evt->services[i].uuid;
    			p_srv_being_discovered->handle_range = p_prim_srvc_disc_rsp_evt->services[i].handle_range;
    
    			NRF_LOG_INFO("Found service UUID %x and its start handle:%d , End handle: %d", p_srv_being_discovered->srv_uuid.uuid,
    			p_srv_being_discovered->handle_range.start_handle, p_srv_being_discovered->handle_range.end_handle);
    			}
    			// If the last service has not been reached, this function must be called again with a new start handle.
    			err_code = sd_ble_gattc_primary_services_discover(conn_hdle,
    			p_prim_srvc_disc_rsp_evt->services[count - 1].handle_range.end_handle + 1,
    			NULL);
    			if(err_code == NRF_SUCCESS)
    			{
    			NRF_LOG_INFO("Discovery done successfully..");
    			}
    			else
    			{
    			NRF_LOG_INFO("Discovery Fail..");
    
    			}
    		//  APP_ERROR_CHECK(err_code);
    		}
    
            err_code = characteristics_discover(p_db_discovery, p_ble_gattc_evt->conn_handle);
    
            if (err_code != NRF_SUCCESS)
            {
                p_db_discovery->discovery_in_progress = false;
    
                NRF_LOG_INFO("Error with discovering the characteristics");
                // Indicate the error to the registered user application.
                discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle);
    
                m_pending_user_evts[0].evt.evt_type    = BLE_DB_DISCOVERY_AVAILABLE;
                m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
            }
        }
        else
        {
            NRF_LOG_INFO("Service UUID 0x%x not found.", p_srv_being_discovered->srv_uuid.uuid);
            // Trigger Service Not Found event to the application.
            discovery_complete_evt_trigger(p_db_discovery, false, p_ble_gattc_evt->conn_handle);
            on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle);
        }
        NRF_LOG_INFO("Services count at end: %d", offset);
         offset = 0;
    }
    

Children
No Data
Related