<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>How to know when database discovery is finished?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/52022/how-to-know-when-database-discovery-is-finished</link><description>I am using the database discovery module in my app (my code is based on the &amp;quot;HRS client&amp;quot; that is one of the SDK examples). I am able to discover multiple services (both custom and adopted) from the remote device just fine, but this part is unclear: how</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 12 Sep 2019 07:49:29 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/52022/how-to-know-when-database-discovery-is-finished" /><item><title>RE: How to know when database discovery is finished?</title><link>https://devzone.nordicsemi.com/thread/209324?ContentTypeID=1</link><pubDate>Thu, 12 Sep 2019 07:49:29 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4c60dec4-f4d7-497e-9cf4-db2b76c322ca</guid><dc:creator>TylerD</dc:creator><description>&lt;p&gt;Thanks for confirming. The original issue seems to be reported over 2 years ago so I&amp;#39;m not holding my breath... EDIT: just saw your update, so I&amp;#39;ll give it a try when the SDK v16 is available.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to know when database discovery is finished?</title><link>https://devzone.nordicsemi.com/thread/209320?ContentTypeID=1</link><pubDate>Thu, 12 Sep 2019 07:43:44 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7ae081ac-f5ef-4bbc-ad24-c50163d69523</guid><dc:creator>bjorn-spockeli</dc:creator><description>&lt;p&gt;It seems that this is a known issue with the DB discovery module&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/20846/getting-service-count-from-database-discovery-module"&gt;https://devzone.nordicsemi.com/f/nordic-q-a/20846/getting-service-count-from-database-discovery-module&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It has been reported internally and I have bumped the issue as well.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;UPDATE:&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This&amp;nbsp;will be fixed&amp;nbsp;in nRF5x SDK v16.0.0. Service count will be valid and also BLE_DB_DISCOVERY_AVAILABLE will be triggered. Will see if I can get hold of the fixed module code.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Best regards&lt;/p&gt;
&lt;p&gt;Bjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to know when database discovery is finished?</title><link>https://devzone.nordicsemi.com/thread/209313?ContentTypeID=1</link><pubDate>Thu, 12 Sep 2019 07:15:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:424d4b5e-e395-438f-b041-5bf18143bb50</guid><dc:creator>TylerD</dc:creator><description>&lt;p&gt;After reading through the code, the event seems to be there (&lt;span&gt;BLE_DB_DISCOVERY_AVAILABLE&amp;nbsp;) but for some reason it is not sent to my app. To me it seems&amp;nbsp;like a bug in the service discovery module code.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to know when database discovery is finished?</title><link>https://devzone.nordicsemi.com/thread/209310?ContentTypeID=1</link><pubDate>Thu, 12 Sep 2019 07:12:40 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:784d3b06-1745-4d7b-b464-827fa9607cf8</guid><dc:creator>bjorn-spockeli</dc:creator><description>&lt;p&gt;HI Tyler,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As far as I understand you should get the same number of events from the DB discovery module as the number of UUIDs you registered, see the MSC at the bottom of this page:&amp;nbsp;&lt;a title="Software Development Kit" href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v15.3.0/lib_ble_db_discovery.html?resultof=%22%42%4c%45%5f%44%42%5f%44%49%53%43%4f%56%45%52%59%5f%43%4f%4d%50%4c%45%54%45%22%20"&gt;nRF5 SDK v15.3.0: Database Discovery Module&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So I think you should be able to increment a counter in&amp;nbsp;&lt;span&gt;db_disc_handler() or in the individual&amp;nbsp;ble_xxx_c_on_db_disc_evt handlers() that are called from&amp;nbsp;db_disc_handler(). Once the counter reaches two(i.e. DIS and your custom service) to you know that DB discovery is complete and you should be able to read the Manuf.name.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Another approach could be to retry the&amp;nbsp;sd_ble_gattc_read() call to read the Manuf.name characteristic when you get the&amp;nbsp;NRF_ERROR_BUSY return code. Either in a while loop or starting an application timer that calls&amp;nbsp;sd_ble_gattc_read() in its callback. The timeout can be very short and if you get&amp;nbsp;NRF_ERROR_BUSY, then you restart the timer. This way you&amp;#39;re not busy-waiting in an interrupt context.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
[quote user="TylerD"]The service discovery module has clearly been designed so that you can configure it to search for multiple services. I think it is missing one more event that would indicate that the module has completed its task.[/quote]
&lt;p&gt;&amp;nbsp;I will provide this feedback to the SDK team.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards&lt;/p&gt;
&lt;p&gt;Bjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to know when database discovery is finished?</title><link>https://devzone.nordicsemi.com/thread/209300?ContentTypeID=1</link><pubDate>Thu, 12 Sep 2019 06:37:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:cde648b9-0e07-44ac-97df-3e37928411cf</guid><dc:creator>TylerD</dc:creator><description>&lt;p&gt;I was reading through the service discovery module code (ble_db_discovery.c) and noticed that this is the event that should be generated when there are no more services to be found:&lt;/p&gt;
&lt;p&gt;BLE_DB_DISCOVERY_AVAILABLE&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s the relevant code snippet, around line #300:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;else
    {
        // No more service discovery is needed.
        p_db_discovery-&amp;gt;discovery_in_progress  = false;
        m_pending_user_evts[0].evt.evt_type    = BLE_DB_DISCOVERY_AVAILABLE;
        m_pending_user_evts[0].evt.conn_handle = conn_handle;
    }&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t see this event generated at all. I have a case statement that handles the events and there is only two events&amp;nbsp;BLE_DB_DISCOVERY_COMPLETE (as expected), but the&amp;nbsp;&lt;span&gt;BLE_DB_DISCOVERY_AVAILABLE is&amp;nbsp;not there. Is there a bug in the service discovery module?&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I am using SDK 15.3.0.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to know when database discovery is finished?</title><link>https://devzone.nordicsemi.com/thread/209293?ContentTypeID=1</link><pubDate>Thu, 12 Sep 2019 06:07:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9481d9d2-b21e-413c-96c5-9470efc6e6cc</guid><dc:creator>TylerD</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;Bj&amp;oslash;rn,&lt;/p&gt;
&lt;p&gt;thanks for the answer. It is clear to me how the discovery of service and the associated handles works for one individual service. However, my question is related to the case where my app is discovering&amp;nbsp;multiple services.&lt;/p&gt;
&lt;p&gt;Here is the problem that I am facing right now: my app is trying to discover the Device Information service and also another&amp;nbsp;vendor specific service with 128-bit UUID. Therefore I am getting two&amp;nbsp;BLE_DB_DISCOVERY_COMPLETE events.&lt;/p&gt;
&lt;p&gt;Upon getting the first&amp;nbsp;BLE_DB_DISCOVERY_COMPLETE (for the Device Information service), my code checks the handles and then tries to read the &lt;strong&gt;Manufacturer Name&lt;/strong&gt;. The call to&amp;nbsp;sd_ble_gattc_read() fails with code&amp;nbsp;NRF_ERROR_BUSY. I assume this is because the service discovery is still going on (to find the other service my app is interested in).&lt;/p&gt;
&lt;p&gt;The&amp;nbsp;question is: when do I know that it is safe to read the characteristics in the Device&amp;nbsp;Information service? I could add some fixed delay in my app, but that&amp;nbsp;does not seem like a real solution.&lt;/p&gt;
&lt;p&gt;The service discovery module has clearly been designed so that you can configure it to search for multiple services. I think it is missing one more event that would indicate that the module has completed its task.&lt;/p&gt;
&lt;p&gt;As you said,&amp;nbsp;BLE_DB_DISCOVERY_COMPLETE indicates that discovery of &lt;strong&gt;one service&lt;/strong&gt; is complete. The problem is that I don&amp;#39;t know how many of these events are still coming in and which of those is the last one.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to know when database discovery is finished?</title><link>https://devzone.nordicsemi.com/thread/209159?ContentTypeID=1</link><pubDate>Wed, 11 Sep 2019 11:51:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c372457f-cc38-471d-8c88-18c209065bcf</guid><dc:creator>bjorn-spockeli</dc:creator><description>&lt;p&gt;Hy Tyler,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;the BLE_DB_DISCOVERY_COMPLETE will be generated when discovery of one service is completed.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/**@brief DB Discovery event type. */
typedef enum
{
    BLE_DB_DISCOVERY_COMPLETE,      /**&amp;lt; Event indicating that the discovery of one service is complete. */
    BLE_DB_DISCOVERY_ERROR,         /**&amp;lt; Event indicating that an internal error has occurred in the DB Discovery module. This could typically be because of the SoftDevice API returning an error code during the DB discover.*/
    BLE_DB_DISCOVERY_SRV_NOT_FOUND, /**&amp;lt; Event indicating that the service was not found at the peer.*/
    BLE_DB_DISCOVERY_AVAILABLE      /**&amp;lt; Event indicating that the DB discovery instance is available.*/
} ble_db_discovery_evt_type_t;
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Hence, you will have to keep of which services that have been discovered, but in our examples I feel that we have shown how to do this.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If we take a look at the ble_app_uart_c example we see that the database discovery module is intialized, i.e. setting the db_disc_handler callback for discovery events in main().&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Then in&amp;nbsp;ble_nus_init() we see that we register the NUS service UUID with the database discovery module using&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;ble_db_discovery_evt_register(&amp;amp;uart_uuid);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;i.e.&amp;nbsp;&lt;span&gt;db_disc_handler() will be called if we find a service with a UUID matching uart_uuid. Now in&amp;nbsp;db_disc_handler() we call&amp;nbsp;ble_nus_c_on_db_disc_evt()&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
{
    ble_nus_c_on_db_disc_evt(&amp;amp;m_ble_nus_c, p_evt);
}

void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt)
{
    ble_nus_c_evt_t nus_c_evt;
    memset(&amp;amp;nus_c_evt,0,sizeof(ble_nus_c_evt_t));

    ble_gatt_db_char_t * p_chars = p_evt-&amp;gt;params.discovered_db.charateristics;

    // Check if the NUS was discovered.
    if (    (p_evt-&amp;gt;evt_type == BLE_DB_DISCOVERY_COMPLETE)
        &amp;amp;&amp;amp;  (p_evt-&amp;gt;params.discovered_db.srv_uuid.uuid == BLE_UUID_NUS_SERVICE)
        &amp;amp;&amp;amp;  (p_evt-&amp;gt;params.discovered_db.srv_uuid.type == p_ble_nus_c-&amp;gt;uuid_type))
    {
        for (uint32_t i = 0; i &amp;lt; p_evt-&amp;gt;params.discovered_db.char_count; i++)
        {
            switch (p_chars[i].characteristic.uuid.uuid)
            {
                case BLE_UUID_NUS_RX_CHARACTERISTIC:
                    nus_c_evt.handles.nus_rx_handle = p_chars[i].characteristic.handle_value;
                    break;

                case BLE_UUID_NUS_TX_CHARACTERISTIC:
                    nus_c_evt.handles.nus_tx_handle = p_chars[i].characteristic.handle_value;
                    nus_c_evt.handles.nus_tx_cccd_handle = p_chars[i].cccd_handle;
                    break;

                default:
                    break;
            }
        }
        if (p_ble_nus_c-&amp;gt;evt_handler != NULL)
        {
            nus_c_evt.conn_handle = p_evt-&amp;gt;conn_handle;
            nus_c_evt.evt_type    = BLE_NUS_C_EVT_DISCOVERY_COMPLETE;
            p_ble_nus_c-&amp;gt;evt_handler(p_ble_nus_c, &amp;amp;nus_c_evt);
        }
    }
}&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Now this function populates the handle values for all the discovered&amp;nbsp;characteristics and places them in a&amp;nbsp;ble_nus_c_evt_t struct. Then the event_type of the&amp;nbsp;ble_nus_c_evt_t&amp;nbsp; struct is set to&amp;nbsp; BLE_NUS_C_EVT_DISCOVERY_COMPLETE and the&amp;nbsp;ble_nus_c_evt_handler is called.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;uint32_t ble_nus_c_handles_assign(ble_nus_c_t               * p_ble_nus,
                                  uint16_t                    conn_handle,
                                  ble_nus_c_handles_t const * p_peer_handles)
{
    VERIFY_PARAM_NOT_NULL(p_ble_nus);

    p_ble_nus-&amp;gt;conn_handle = conn_handle;
    if (p_peer_handles != NULL)
    {
        p_ble_nus-&amp;gt;handles.nus_tx_cccd_handle = p_peer_handles-&amp;gt;nus_tx_cccd_handle;
        p_ble_nus-&amp;gt;handles.nus_tx_handle      = p_peer_handles-&amp;gt;nus_tx_handle;
        p_ble_nus-&amp;gt;handles.nus_rx_handle      = p_peer_handles-&amp;gt;nus_rx_handle;
    }
    return NRF_SUCCESS;
}

/**@snippet [Handling events from the ble_nus_c module] */
static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_ble_nus_evt)
{
    ret_code_t err_code;

    switch (p_ble_nus_evt-&amp;gt;evt_type)
    {
        case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
            NRF_LOG_INFO(&amp;quot;Discovery complete.&amp;quot;);
            err_code = ble_nus_c_handles_assign(p_ble_nus_c, p_ble_nus_evt-&amp;gt;conn_handle, &amp;amp;p_ble_nus_evt-&amp;gt;handles);
            APP_ERROR_CHECK(err_code);
            
            err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);
            APP_ERROR_CHECK(err_code);
            NRF_LOG_INFO(&amp;quot;Connected to device with Nordic UART Service.&amp;quot;);
            break;
    .
    .
    .
    }
}&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This function calls&amp;nbsp;ble_nus_c_handles_assign which assigns all the handles to the global ble_nus_c_t struct declared by the&amp;nbsp;BLE_NUS_C_DEF(m_ble_nus_c) macro in main.c&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Forward declaration of the ble_nus_t type.
typedef struct ble_nus_c_s ble_nus_c_t;

/**@brief NUS Client structure. */
struct ble_nus_c_s
{
    uint8_t                 uuid_type;      /**&amp;lt; UUID type. */
    uint16_t                conn_handle;    /**&amp;lt; Handle of the current connection. Set with @ref ble_nus_c_handles_assign when connected. */
    ble_nus_c_handles_t     handles;        /**&amp;lt; Handles on the connected peer device needed to interact with it. */
    ble_nus_c_evt_handler_t evt_handler;    /**&amp;lt; Application event handler to be called when there is an event related to the NUS. */
};&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;All calls that involve reading/writing to these characteristics should use the handles stored in this global struct.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So the TLDR version is that you should not allow the nRF to perform any operations on characteristics for a given service until the central module for the said service, e.g. ble_nus_c, has issued an event indicating that the service has been discovered, e.g.&amp;nbsp;BLE_NUS_C_EVT_DISCOVERY_COMPLETE.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I hope that made sense. If not, just ask me to clarify in a comment.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Best regards&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Bjørn&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>