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

gatt service inquiry

Hi,

In addition to listening the advertiser's and beacon data we also need to offer the master application - which is connected to BLE-module via UART - the possibility to connect to peripheral and get information of available GATT-services. For this we need to be able to inquire service uuids from the connected peripheral.

I've been browsing through the examples but not been able to find out the solution for this. There are samples for listening the defined services, but not one for getting the information of all the available services.

Could anyone please guide me to the correct example, or give me some step-by-step information for building such an application.

Devkit used is nRF52840-DK, SDK revision is nRF5_SDK_16.0.0_98a08e2

Regards, Jukka

  • Hi Jukka

    It seems like you're looking for a way to discover services. Have you checked out our database discovery module which handles service discovery on GATT servers? The ble_app_blinky_c example for one is an example using this to discover the services available in the peripheral it connects to. 

    Alternatively, you can run discovery algorithms yourself by using sd_ble_gattc_XX functions, but I personally think the module is the easiest to use.

    Best regards,

    Simon

  • Thänx for the response, Simon

    So it is the callback function db_disc_handler() handling - or routing - the database discovery events. I have one beacon box which looks like the following in the Nordic android tool:

    showing some services available, of which the Battery service seems to be the only standardized.

    However our software shows the following output when connecting to the same device :

    Advertising type=0x0B, device WGX_iBeacon, addrtype=1, addr=7571823740D8  rssi=-76, phy=1, sphy=255 
    Match found, connecting...
    Connecting, started 30s connection timer
    scan_evt_handler: Connecting to target 7571823740d8
    ble_evt_handler: BLE_GAP_EVT_CONNECTED
    gatt_evt_handler: MTU exchange completed, Ble NUS max data length set to 20 bytes
    ble_evt_handler: BLE_GATTC_EVT_EXCHANGE_MTU_RSP: 23 bytes
    gatt_evt_handler: NRF_BLE_GATT_EVT_DATA_LENGTH_UPDATED
    ble_evt_handler: BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT
    db_disc_handler: BLE_DB_DISCOVERY_SRV_NOT_FOUND
    db_disc_handler: BLE_DB_DISCOVERY_AVAILABLE
    ble_evt_handler: BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP
    ble_evt_handler: BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST
    ble_evt_handler: BLE_GAP_EVT_CONN_PARAM_UPDATE
    ble_evt_handler: BLE_GAP_EVT_DISCONNECTED

    So it seems that the same services are not found with our own application, which is based on the ble_app_uart_c example.

    Rgrds, Jukka

  • Hi

    Can you upload a snippet showing how you've added the discovery module in your application? There must be some configurations that haven't been done properly.

    Best regards,

    Simon

  • Hi,

    Basically the initialization procedure is the following:

    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    
    
    /**@brief Function for initializing the GATT library. */
    void gatt_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_gatt_att_mtu_central_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing the UART. */
    static void uart_init(void)
    {
        ret_code_t err_code;
    
        app_uart_comm_params_t const comm_params =
        {
            .rx_pin_no    = RX_PIN_NUMBER,
            .tx_pin_no    = TX_PIN_NUMBER,
            .rts_pin_no   = RTS_PIN_NUMBER,
            .cts_pin_no   = CTS_PIN_NUMBER,
            .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
            .use_parity   = false,
            .baud_rate    = UART_BAUDRATE_BAUDRATE_Baud115200
        };
    
        APP_UART_FIFO_INIT(&comm_params,
                           UART_RX_BUF_SIZE,
                           UART_TX_BUF_SIZE,
                           uart_event_handle,
                           APP_IRQ_PRIORITY_LOWEST,
                           err_code);
    
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for initializing the Nordic UART Service (NUS) client. */
    static void nus_c_init(void)
    {
        ret_code_t       err_code;
        ble_nus_c_init_t init;
    
        init.evt_handler = ble_nus_c_evt_handler;
    
        err_code = ble_nus_c_init(&m_ble_nus_c, &init);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing buttons and leds. */
    static void buttons_leds_init(void)
    {
        ret_code_t err_code;
        bsp_event_t startup_event;
    
        err_code = bsp_init(BSP_INIT_LEDS, bsp_event_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_btn_ble_init(NULL, &startup_event);
        APP_ERROR_CHECK(err_code);
    }
    
    static ret_code_t mtimer_err_code;
    
    /**@brief Function for initializing the timer. */
    static void timer_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    
        mtimer_err_code = app_timer_create(&m_connection_timer, APP_TIMER_MODE_SINGLE_SHOT, connection_timer_tick_callback);
    }
    
    
    /**@brief Function for initializing the nrf log module. */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    
    /**@brief Function for initializing power management.
     */
    static void power_management_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /** @brief Function for initializing the database discovery module. */
    static void db_discovery_init(void)
    {
        ble_db_discovery_init_t db_init;
        
        memset(&db_init, 0, sizeof(ble_db_discovery_init_t));
        
        db_init.evt_handler  = db_disc_handler;
        db_init.p_gatt_queue = &m_ble_gatt_queue;
        
        ret_code_t err_code = ble_db_discovery_init(&db_init);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling the idle state (main loop).
     *
     * @details Handles any pending log operations, then sleeps until the next event occurs.
     */
    static void idle_state_handle(void)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
        }
    }
    
    
    int main(void)
    {
        // Initialize.
        log_init();
        timer_init();
        uart_init();
        buttons_leds_init();
        db_discovery_init();
        power_management_init();
        ble_stack_init();
        gatt_init();
        nus_c_init();
        scan_init();
    
        // Start execution.
        NRF_LOG_INFO("BLE UART central example started.");
        scan_start();
    
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }
    

    And the sdk_config.h is attached.3581.sdk_config.h

    BR: Jukka

  • Okay, I can't see anything strange going on here. I noticed while digging through the documentation, that only the following descriptors will be searched for at the peer:

    • Client Characteristic Configuration
    • Characteristic Extended Properties
    • Characteristic User Description
    • Report Reference.

    Can you confirm that your services include any of these descriptors?

    Best regards,

    Simon

Related