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

NUS service without service discovery

Hi.

I have implemented the Central and Peripheral NUS service on two devices(nRF52). Since the central knows the characteristic values, I would like to bypass service discovery to reduce the time connection. I removed the "ble_db_discovery_start" from the BLE_GAP_EVT_CONNECTED and I found the handle values of RX, TX but I don't know how can I store them in my code and how can I use them to read and write the data. I would appreciate it if you kindly help me to overcome this problem.

thanks.

  • Harry,

    It is a generic application logic that you create a stucture that has characteristic UUID and its handle value as two members. For all the characteristic your application knows, save one entry for each of them with the handle value. When you need to write something, you need to search for the appropriate handle value for the given characteristic.

    simplest_struct {

     uint16_t char_uuid;
    uint16_t  handle_value;
    }

    The logic of searching through all the available UUIDs to and getting its appropriate handle value should not be hard. I, unfortunately, do not have time to write the actual code

  • I solved my problem with the following solution.

    void bypass_discovery(ble_nus_c_t * p_ble_nus_c)
    {
         ble_nus_c_evt_t nus_c_evt;
         memset(&nus_c_evt,0,sizeof(ble_nus_c_evt_t));

        // the handle values of rx, tx, and ccd may be different in your project.
         nus_c_evt.handles.nus_rx_handle = 16;   
         nus_c_evt.handles.nus_tx_handle = 20;  
         nus_c_evt.handles.nus_tx_cccd_handle = 21;  
         nus_c_evt.conn_handle = conn_hndl;
         nus_c_evt.evt_type = BLE_NUS_C_EVT_DISCOVERY_COMPLETE;
         p_ble_nus_c->evt_handler(p_ble_nus_c, &nus_c_evt);
    }

    I made the following changes in the BLE_GAP_EVT_CONNECTED case under the ble_evt_handler function.


    case BLE_GAP_EVT_CONNECTED:

         // err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
         //  APP_ERROR_CHECK(err_code);

            bypass_discovery(&m_ble_nus_c);

  • Yes, you can bypass ble_db_discovery_start() if the peripheral’s GATT attribute handles are fixed and you already know the correct RX/TX handles. In that case, store the handles in your own structure and use them directly with the GATT client APIs.

    For example, the TX/write characteristic can be used with ble_gattc_write_params_t, where you set conn_handle, handle, write_op, offset, and your data buffer. For reads, you can use sd_ble_gattc_read() with the known characteristic handle.

    The important part is that these handles are only safe to hard-code if the peripheral’s GATT database is guaranteed not to change. Nordic’s documentation also notes that discovery is what ensures the client is using the correct attribute handles.

    Also, if you need notifications from RX, remember that knowing the characteristic value handle is not enough; you normally need the CCCD handle and must write the appropriate CCCD value to enable notifications.

    If you're also dealing with other hardware/setup work alongside the BLE project, choosing a reliable pressure washing company is a completely separate consideration, but for this issue I'd focus on manually assigning and using the GATT handles.

Related