<?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 do you program device to update its own custom characteristic value after a given criteria?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/84557/how-do-you-program-device-to-update-its-own-custom-characteristic-value-after-a-given-criteria</link><description>I am still learning how to develop on the nRF52 DK. Nevertheless there are many BLE devices in the market that change their own characteristic / attribute values after connection has been established and some criteria is met. For example, in the following</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 14 Feb 2022 19:50:34 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/84557/how-do-you-program-device-to-update-its-own-custom-characteristic-value-after-a-given-criteria" /><item><title>RE: How do you program device to update its own custom characteristic value after a given criteria?</title><link>https://devzone.nordicsemi.com/thread/352987?ContentTypeID=1</link><pubDate>Mon, 14 Feb 2022 19:50:34 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6833d6fa-0db3-4cca-b018-9968afea54ea</guid><dc:creator>tjhasan</dc:creator><description>&lt;p&gt;After some more trial and error I eventually got it to work. It was essentially just as you said: I had to adjust my code to not just read the first element due to how arrays and array pointers work in C.&lt;/p&gt;
&lt;p&gt;To anyone that finds this thread, the issue was in the method body of the &lt;strong&gt;ble_cus_custom_value_update(): &lt;/strong&gt;function. See here for the full implementation as well as comments on what was changed to fix it:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static void on_write(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
{
    Number_Of_Updates += 1;
    ble_gatts_evt_write_t const * p_evt_write = &amp;amp;p_ble_evt-&amp;gt;evt.gatts_evt.params.write;
    
    // Custom Value Characteristic Written to.
    if (p_evt_write-&amp;gt;handle == p_cus-&amp;gt;custom_value_handles.value_handle)
    {
        nrf_gpio_pin_toggle(LED_4);
    }

    // Check if the Custom value CCCD is written to and that the value is the appropriate length, i.e 2 bytes.
    if ((p_evt_write-&amp;gt;handle == p_cus-&amp;gt;custom_value_handles.cccd_handle)
        &amp;amp;&amp;amp; (p_evt_write-&amp;gt;len == 2)
       )
    {
        // CCCD written, call application event handler
        if (p_cus-&amp;gt;evt_handler != NULL)
        {
            ble_cus_evt_t evt;

            if (ble_srv_is_notification_enabled(p_evt_write-&amp;gt;data))
            {
                evt.evt_type = BLE_CUS_EVT_NOTIFICATION_ENABLED;
            }
            else
            {
                evt.evt_type = BLE_CUS_EVT_NOTIFICATION_DISABLED;
            }
            // Call the application event handler.
            p_cus-&amp;gt;evt_handler(p_cus, &amp;amp;evt);
        }
    }

    if (Number_Of_Updates == 4)
    {
        uint8_t value[18] = {0xAB, 0x17, 0x3E, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA};        
        //THE FOLLOWING FUNCTION CALL WAS ADJUSTED TO PASS A POINTER TO THE ARRAY.
        ble_cus_custom_value_update(p_cus, *value);
    }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;uint32_t ble_cus_custom_value_update(ble_cus_t * p_cus, uint8_t *custom_value)
{
    NRF_LOG_INFO(&amp;quot;In ble_cus_custom_value_update. \r\n&amp;quot;); 
    if (p_cus == NULL)
    {
        return NRF_ERROR_NULL;
    }

    uint32_t err_code = NRF_SUCCESS;
    ble_gatts_value_t gatts_value;

    // Initialize value struct.
    memset(&amp;amp;gatts_value, 0, sizeof(gatts_value));

    gatts_value.len     = 18;
    gatts_value.offset  = 0;
    
    /**
    * The following line was originally:
    *       gatts_value.p_value = &amp;amp;custom_value;
    * However this made the gatts_value.p_value equal to only the first
    * element of the array. In order for p_value to equal the entire array,
    * simply pass the array with no referencing or dereferencing.
    */
    gatts_value.p_value = custom_value;

    // Update database.
    err_code = sd_ble_gatts_value_set(p_cus-&amp;gt;conn_handle,
                                      p_cus-&amp;gt;custom_value_handles.value_handle,
                                      &amp;amp;gatts_value);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }



    // Send value if connected and notifying.
    if ((p_cus-&amp;gt;conn_handle != BLE_CONN_HANDLE_INVALID)) 
    {
        ble_gatts_hvx_params_t hvx_params;

        memset(&amp;amp;hvx_params, 0, sizeof(hvx_params));

        hvx_params.handle = p_cus-&amp;gt;custom_value_handles.value_handle;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = gatts_value.offset;
        hvx_params.p_len  = &amp;amp;gatts_value.len;
        hvx_params.p_data = gatts_value.p_value;

        err_code = sd_ble_gatts_hvx(p_cus-&amp;gt;conn_handle, &amp;amp;hvx_params);
        NRF_LOG_INFO(&amp;quot;sd_ble_gatts_hvx result: %x. \r\n&amp;quot;, err_code); 
    }
    else
    {
        err_code = NRF_ERROR_INVALID_STATE;
        NRF_LOG_INFO(&amp;quot;sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE. \r\n&amp;quot;); 
    }
    return err_code;
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Thank you very much for your help!!!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How do you program device to update its own custom characteristic value after a given criteria?</title><link>https://devzone.nordicsemi.com/thread/352821?ContentTypeID=1</link><pubDate>Mon, 14 Feb 2022 09:21:36 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d93bb1e3-cfc3-4f54-aad1-8838f6bac464</guid><dc:creator>Juliusc</dc:creator><description>&lt;p&gt;no worries. Those are more C-related questions but yes, the function needs to be declared as&amp;nbsp;&lt;strong&gt;ble_cus_custom_value_update(p_cus, *value);&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;the value points to the first address of the array you are handing over. This is necessary to be able to access all elements from the value array inside the update function.&lt;/p&gt;
&lt;p&gt;read more on this here, Im in no position to teach this well enough. &lt;a href="https://www.programiz.com/c-programming/c-pointers-arrays"&gt;www.programiz.com/.../c-pointers-arrays&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How do you program device to update its own custom characteristic value after a given criteria?</title><link>https://devzone.nordicsemi.com/thread/352774?ContentTypeID=1</link><pubDate>Sun, 13 Feb 2022 03:41:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e5178557-0cc7-48b7-bf7f-3c36aefe2fd9</guid><dc:creator>tjhasan</dc:creator><description>&lt;p&gt;I&amp;#39;m so sorry, I&amp;#39;m really new to this syntax so maybe this is a really stupid question, but how am I only passing a single custom value in the code above? I create the array &amp;quot;&lt;strong&gt;value[18] = {...}&lt;/strong&gt;&amp;quot; and pass it to the function:&lt;strong&gt;&amp;nbsp;ble_cus_custom_value_update(p_cus, value).&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;How should I change this function call to make it work? Should it be:&lt;br /&gt;&lt;strong&gt;ble_cus_custom_value_update(p_cus, &amp;amp;value);&amp;nbsp;&lt;/strong&gt;or&lt;br /&gt;&lt;strong&gt;ble_cus_custom_value_update(p_cus, *value);&lt;/strong&gt; ?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Again I apologize for the dumb question, I&amp;#39;m genuinely still a novice at this.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How do you program device to update its own custom characteristic value after a given criteria?</title><link>https://devzone.nordicsemi.com/thread/352735?ContentTypeID=1</link><pubDate>Fri, 11 Feb 2022 22:47:41 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b40f8cd1-a08a-44d8-a9c6-4e1441a5cc7c</guid><dc:creator>Juliusc</dc:creator><description>&lt;p&gt;So as far as I can see you only hand over a single custom value to the update function. You need to handle over a pointer to the value array that you have set in your on_write() function.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How do you program device to update its own custom characteristic value after a given criteria?</title><link>https://devzone.nordicsemi.com/thread/352716?ContentTypeID=1</link><pubDate>Fri, 11 Feb 2022 18:21:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:274fd3f6-b885-4a71-bae4-3d512a4d558a</guid><dc:creator>tjhasan</dc:creator><description>&lt;p&gt;I&amp;#39;m pretty sure the answer to both of those questions is yes. &lt;/p&gt;
&lt;p&gt;I have set a flag in my on_write() function that checks for the 4th write call. Once it finds it, it calls the ble_cus_custom_value_update() function as seen in the code snippet above. Here is my ble_cus_custom_value_update() function:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;uint32_t ble_cus_custom_value_update(ble_cus_t * p_cus, uint8_t custom_value)
{
    NRF_LOG_INFO(&amp;quot;In ble_cus_custom_value_update. \r\n&amp;quot;); 
    if (p_cus == NULL)
    {
        return NRF_ERROR_NULL;
    }

    uint32_t err_code = NRF_SUCCESS;
    ble_gatts_value_t gatts_value;

    // Initialize value struct.
    memset(&amp;amp;gatts_value, 0, sizeof(gatts_value));

    //gatts_value.len     = sizeof(uint8_t);
    gatts_value.len     = 18;
    gatts_value.offset  = 0;
    gatts_value.p_value = &amp;amp;custom_value;

    // Update database.
    err_code = sd_ble_gatts_value_set(p_cus-&amp;gt;conn_handle,
                                      p_cus-&amp;gt;custom_value_handles.value_handle,
                                      &amp;amp;gatts_value);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }



    // Send value if connected and notifying.
    if ((p_cus-&amp;gt;conn_handle != BLE_CONN_HANDLE_INVALID)) 
    {
        ble_gatts_hvx_params_t hvx_params;

        memset(&amp;amp;hvx_params, 0, sizeof(hvx_params));

        hvx_params.handle = p_cus-&amp;gt;custom_value_handles.value_handle;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = gatts_value.offset;
        hvx_params.p_len  = &amp;amp;gatts_value.len;
        hvx_params.p_data = gatts_value.p_value;

        err_code = sd_ble_gatts_hvx(p_cus-&amp;gt;conn_handle, &amp;amp;hvx_params);
        NRF_LOG_INFO(&amp;quot;sd_ble_gatts_hvx result: %x. \r\n&amp;quot;, err_code); 
    }
    else
    {
        err_code = NRF_ERROR_INVALID_STATE;
        NRF_LOG_INFO(&amp;quot;sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE. \r\n&amp;quot;); 
    }
    return err_code;
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Is there something I should add to this that I&amp;#39;m missing? After the 4th write, I create the custom value to send the ble_cus_custom_value_update() parameter so I&amp;#39;m pretty sure the values are being stored correctly in hvx_params.p_data.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How do you program device to update its own custom characteristic value after a given criteria?</title><link>https://devzone.nordicsemi.com/thread/352235?ContentTypeID=1</link><pubDate>Thu, 10 Feb 2022 08:30:40 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6cd0127d-daa9-4ec3-b2aa-31af90efb1b5</guid><dc:creator>Juliusc</dc:creator><description>&lt;p&gt;have you set a breakpoint in your ble_cus_custom_value_update() function? Are those values stored correctly in hvx_params.p_data?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How do you program device to update its own custom characteristic value after a given criteria?</title><link>https://devzone.nordicsemi.com/thread/352183?ContentTypeID=1</link><pubDate>Wed, 09 Feb 2022 19:13:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9602036a-7c73-466b-b5b9-c6d728ac253c</guid><dc:creator>tjhasan</dc:creator><description>&lt;p&gt;&lt;span style="font-family:arial, helvetica, sans-serif;"&gt;I&amp;#39;m almost there! I&amp;#39;ve added a flag within the on_write() function and the device now does indeed change the characteristic value after the 4th write. However, the value that is written is &lt;em&gt;not&lt;/em&gt; the value that I want to change it to.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:arial, helvetica, sans-serif;"&gt;Below is my on_write() function:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static void on_write(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
{
    Number_Of_Updates += 1;
    ble_gatts_evt_write_t const * p_evt_write = &amp;amp;p_ble_evt-&amp;gt;evt.gatts_evt.params.write;
    
    // Custom Value Characteristic Written to.
    if (p_evt_write-&amp;gt;handle == p_cus-&amp;gt;custom_value_handles.value_handle)
    {
        nrf_gpio_pin_toggle(LED_4);
    }

    // Check if the Custom value CCCD is written to and that the value is the appropriate length, i.e 2 bytes.
    if ((p_evt_write-&amp;gt;handle == p_cus-&amp;gt;custom_value_handles.cccd_handle)
        &amp;amp;&amp;amp; (p_evt_write-&amp;gt;len == 2)
       )
    {
        // CCCD written, call application event handler
        if (p_cus-&amp;gt;evt_handler != NULL)
        {
            ble_cus_evt_t evt;

            if (ble_srv_is_notification_enabled(p_evt_write-&amp;gt;data))
            {
                evt.evt_type = BLE_CUS_EVT_NOTIFICATION_ENABLED;
            }
            else
            {
                evt.evt_type = BLE_CUS_EVT_NOTIFICATION_DISABLED;
            }
            // Call the application event handler.
            p_cus-&amp;gt;evt_handler(p_cus, &amp;amp;evt);
        }
    }

    if (Number_Of_Updates == 4)
    {
        uint8_t value[18] = {0xD3, 0x17, 0x3E, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA};        
        ble_cus_custom_value_update(p_cus, value);
    }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#000000;font-family:arial, helvetica, sans-serif;font-size:inherit;"&gt;Near the end of the function you can see my flag that catches the function after 4 updates have been sent. Within this if statement I create the hardcoded value that I want to send. In this case it is D3-17-3E-18-00-00-00-00-00-00-03-01-00-00-00-00-00-EA. However what is actually sent to the device is the following: &lt;span style="float:none;font-style:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:nowrap;"&gt;7C-1C-71-1D-00-00-00-00-00-00-03-01-00-00-00-00-00-EA.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#000000;font-family:arial, helvetica, sans-serif;font-size:inherit;"&gt;&lt;span style="float:none;font-style:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:nowrap;"&gt;What is going on here and how would I go about fixing this?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How do you program device to update its own custom characteristic value after a given criteria?</title><link>https://devzone.nordicsemi.com/thread/352009?ContentTypeID=1</link><pubDate>Wed, 09 Feb 2022 10:27:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c8c8a015-d04a-445e-a139-ea5d34768a9c</guid><dc:creator>Juliusc</dc:creator><description>&lt;p&gt;Hi, I would simply set a flag after the 4th receive (do this in the on_write function)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>