<?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>s140 - GATTS Handle Value Notification</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/69440/s140---gatts-handle-value-notification</link><description>Hi everyone, 
 I am trying to understand the GATTS Handle Value Notification diagram. 
 From what I have understand so far is tha the soft device keeps a buffer (ATT table) where packets are placed before transmission. So each time calling sd_ble_gatts_hvx</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 18 Dec 2020 06:55:39 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/69440/s140---gatts-handle-value-notification" /><item><title>RE: s140 - GATTS Handle Value Notification</title><link>https://devzone.nordicsemi.com/thread/285748?ContentTypeID=1</link><pubDate>Fri, 18 Dec 2020 06:55:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:56cfecab-b90c-4d34-9377-ebdffb73e038</guid><dc:creator>Nikosant03</dc:creator><description>&lt;p&gt;Thank you for your support Hung!!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: s140 - GATTS Handle Value Notification</title><link>https://devzone.nordicsemi.com/thread/285704?ContentTypeID=1</link><pubDate>Thu, 17 Dec 2020 17:10:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1d17233f-d9ab-45c7-aeb1-8eaac0d35a5c</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;Correct :)&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: s140 - GATTS Handle Value Notification</title><link>https://devzone.nordicsemi.com/thread/285686?ContentTypeID=1</link><pubDate>Thu, 17 Dec 2020 15:28:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9f06e3c6-bb01-4798-839a-d58e73628b68</guid><dc:creator>Nikosant03</dc:creator><description>&lt;p&gt;Very nice flow!! Thanks a lot for your advice and your time!!&lt;/p&gt;
&lt;p&gt;If I want to transmit every lets say 20ms then the interrupt&amp;nbsp;at the start of the flow will be actually a timer right?&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1608218809076v1.png" alt=" " /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: s140 - GATTS Handle Value Notification</title><link>https://devzone.nordicsemi.com/thread/285667?ContentTypeID=1</link><pubDate>Thu, 17 Dec 2020 14:44:10 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8cf4856e-8c3f-4534-aa6e-6e07bcda97f7</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;Yes, if you have more packet queued than the number of packets being sent you will have NRF_ERROR_RESOURCE.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t see much point of keeping a timer in this case.&lt;/p&gt;
&lt;p&gt;You can think of doing something like this:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/1024x653/__key/communityserver-discussions-components-files/4/pastedimage1608216226292v2.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: s140 - GATTS Handle Value Notification</title><link>https://devzone.nordicsemi.com/thread/285390?ContentTypeID=1</link><pubDate>Wed, 16 Dec 2020 15:13:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a848aeef-359f-43f5-ab92-ae9371679987</guid><dc:creator>Nikosant03</dc:creator><description>&lt;p&gt;Thank you Hung, now things are much more clear to me&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
[quote userid="2121" url="~/f/nordic-q-a/69440/s140---gatts-handle-value-notification/285261#285261"]&amp;nbsp;In the code, you can just break after you receive&amp;nbsp;NRF_ERROR_RESOURCES. After that you wait for&amp;nbsp;BLE_GATTS_EVT_HVN_TX_COMPLETE[/quote]
&lt;p&gt;Using a timer something like that I believe should be fine right?&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1608130166572v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I believe the reason that could cause the sd buffer&amp;nbsp;to&amp;nbsp;get full is in case that buffering happens faster than the packet transmission, right? So, what are the possible reasons that could cause the packet to not be transmitted and remain in the sd buffer causing high queuing and finally&amp;nbsp;NRF_ERROR_RESOURCES?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: s140 - GATTS Handle Value Notification</title><link>https://devzone.nordicsemi.com/thread/285261?ContentTypeID=1</link><pubDate>Wed, 16 Dec 2020 09:43:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:07190c26-16cc-4a48-9901-586ee91ee051</guid><dc:creator>Hung Bui</dc:creator><description>[quote user="Nikosant03"]So the sd buffer holds the packets that are going to be transmitted while the ATT table holds the information regarding the attributes (services, characteristics, descriptors) such as handle, UUID, and ATT value, &lt;strong&gt;right&lt;/strong&gt;?[/quote]
&lt;p&gt;&amp;nbsp;==&amp;gt; Correct&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
[quote user="Nikosant03"]So despite that&amp;nbsp;&lt;span&gt;sd_ble_gatts_hvx() may return&amp;nbsp;&lt;strong&gt;NRF_ERROR_RESOURCES&amp;nbsp;&lt;/strong&gt; the value of ATT table will be updated (I do not understand the reason behind that..). The ATT table value is updated for every&amp;nbsp;&lt;strong&gt;sd_ble_gatts_hvx()&lt;/strong&gt; call regardless &lt;strong&gt;if it was success or not&lt;/strong&gt;?&lt;/span&gt;[/quote]
&lt;p&gt;==&amp;gt; Correct, please check the description of&amp;nbsp;&lt;strong&gt;sd_ble_gatts_hvx() &lt;/strong&gt;function in ble_gatts.h&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
[quote user="Nikosant03"]Meaning that the buffer was full at that specific moment in time due to other activities? So I believe that before buffering&amp;nbsp;app_value_4 a&amp;nbsp;&amp;nbsp;&lt;strong&gt;BLE_GATTS_EVT_HVN_TX_COMPLETE&lt;/strong&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;event had preceded&amp;nbsp;&lt;strong&gt;right?&lt;/strong&gt;[/quote]
&lt;p&gt;&amp;nbsp;==&amp;gt; Yes. It could be a write command has been executed. or a notification previously queued now sent.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
[quote user="Nikosant03"]&lt;strong&gt;Something like that&lt;/strong&gt;?[/quote]
&lt;p&gt;&amp;nbsp;In the code, you can just break after you receive&amp;nbsp;NRF_ERROR_RESOURCES. After that you wait for&amp;nbsp;BLE_GATTS_EVT_HVN_TX_COMPLETE . When you receive that event, you can call the loop again, or you can turn on a flag to continue the loop (of course you shouldn&amp;#39;t wait infinitely in a loop wait for that event, should better put the CPU to sleep).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
[quote user="Nikosant03"]The return value is the number of packets was sent in the same connection event?[/quote]
&lt;p&gt;&amp;nbsp;==&amp;gt; Correct, in the last connect event.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: s140 - GATTS Handle Value Notification</title><link>https://devzone.nordicsemi.com/thread/285188?ContentTypeID=1</link><pubDate>Tue, 15 Dec 2020 20:08:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7ad85b9d-14bc-432a-88b9-af6339dcb4e0</guid><dc:creator>Nikosant03</dc:creator><description>&lt;p&gt;Hi Hung and thank you for your answer!!&lt;/p&gt;
[quote userid="2121" url="~/f/nordic-q-a/69440/s140---gatts-handle-value-notification/284848#284848"]The softdevice buffers are the buffers for the out going packets, the notification packets for example. When the ATT table is the table that store the value of the attribute locally[/quote]
&lt;p&gt;I think that this is clear to me. So the sd buffer holds the packets that are going to be transmitted while the ATT table holds the information regarding the attributes (services, characteristics, descriptors) such as handle, UUID, and ATT value, &lt;strong&gt;right&lt;/strong&gt;?&lt;/p&gt;
&lt;p&gt;So despite that&amp;nbsp;&lt;span&gt;sd_ble_gatts_hvx() may return&amp;nbsp;&lt;strong&gt;NRF_ERROR_RESOURCES&amp;nbsp;&lt;/strong&gt; the value of ATT table will be updated (I do not understand the reason behind that..). The ATT table value is updated for every&amp;nbsp;&lt;strong&gt;sd_ble_gatts_hvx()&lt;/strong&gt; call regardless &lt;strong&gt;if it was success or not&lt;/strong&gt;?&lt;/span&gt;&lt;/p&gt;
[quote userid="2121" url="~/f/nordic-q-a/69440/s140---gatts-handle-value-notification/284848#284848"]For example in the Variant #1 case you pointed to, the sd_ble_gatts_hvx(app_value_3) returned ERR_RESOURCE[/quote]
&lt;p&gt;&lt;span&gt;Meaning that the buffer was full at that specific moment in time due to other activities? So I believe that before buffering&amp;nbsp;app_value_4 a&amp;nbsp;&amp;nbsp;&lt;strong&gt;BLE_GATTS_EVT_HVN_TX_COMPLETE&lt;/strong&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;event had preceded&amp;nbsp;&lt;strong&gt;right?&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
[quote userid="2121" url="~/f/nordic-q-a/69440/s140---gatts-handle-value-notification/284848#284848"]So basically, what you do is to call&amp;nbsp;sd_ble_gatts_hvx() until you receive&amp;nbsp;&lt;strong&gt;NRF_ERROR_RESOURCES&lt;/strong&gt;&amp;nbsp;, then you wait for&amp;nbsp;&lt;strong&gt;BLE_GATTS_EVT_HVN_TX_COMPLETE&lt;/strong&gt;&amp;nbsp; event, and continue calling&amp;nbsp;sd_ble_gatts_hvx()[/quote]
&lt;p&gt;&lt;span&gt;&lt;strong&gt;Something like that&lt;/strong&gt;?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define QUEUE_SIZE 4


// after the app_timer expire buffer 4 notifications
for (uint8_t i = 0; i &amp;lt; QUEUE_SIZE; i++) {

  error_code = sd_ble_gatts_hvx();
  // error filtering
  if (error_code != NRF_ERROR_RESOURCES) {
    APP_ERROR_CHECK(error_code);
  }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
[quote userid="2121" url="~/f/nordic-q-a/69440/s140---gatts-handle-value-notification/284848#284848"]You can read the value return in the&amp;nbsp;&lt;strong&gt;&amp;nbsp;BLE_GATTS_EVT_HVN_TX_COMPLETE&amp;nbsp;&lt;/strong&gt;to know how many&amp;nbsp;sd_ble_gatts_hvx() you should call.[/quote]
&lt;p&gt;The return value is the number of packets was sent in the same connection event?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;
&lt;p&gt;Nick&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: s140 - GATTS Handle Value Notification</title><link>https://devzone.nordicsemi.com/thread/284848?ContentTypeID=1</link><pubDate>Mon, 14 Dec 2020 15:35:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ecb42733-0f46-4fa8-8f0d-15b5e599b45e</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;Hi Nick,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;There is a difference between &amp;quot;Att table&amp;quot; and the softdevice buffers. They are not the same. The softdevice buffers are the buffers for the out going packets, the notification packets for example. When the ATT table is the table that store the value of the attribute locally. They are not the same. For example in the Variant #1 case you pointed to, the sd_ble_gatts_hvx(app_value_3) returned ERR_RESOURCE (for some reasons, explained later) then that mean the notification for app_value_3 will not be queued, but the value in the att_table is still updated.&amp;nbsp;&lt;br /&gt;And then the next call for sd_ble_gatts_hvx(app_value_4) success and the notification packet will be queued, and the local att_table is updated. Only 3 notification packets will be sent.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It&amp;#39;s true that you can send 6 packets (or even more) in one connection interval, but there is no guarantee that you always can send 6 packets. If the event length is not configured long enough for such many packets, or if the peer device doesn&amp;#39;t want to take multiple packet, you will have less. Also the buffer size can be 6 (or more) but it can be other activities that require some of the buffers. So you may have less number of the notification packet you can queue.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Even if a packet is queued, there is no guarantee that it will be sent in the next connection event. As I mentioned, the peer device may only accept 1 packet per connection event. This answer your question on why in variant #2 app_value_1 and app_value_2 is not sent at the same connection event.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When you receive&amp;nbsp;&lt;strong&gt;&lt;span&gt;BLE_GATTS_EVT_HVN_TX_COMPLETE&lt;/span&gt;&lt;/strong&gt;&lt;span&gt;&amp;nbsp;() there is a chance that you can queue more packet, but it&amp;#39;s not 100% sure you can, because there could be some other activity that already take the buffer (for example if you have&amp;nbsp;other activity&amp;nbsp;that add a write command, write command and notification send the same buffers).&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So basically, what you do is to call&amp;nbsp;sd_ble_gatts_hvx() until you receive&amp;nbsp;&lt;strong&gt;NRF_ERROR_RESOURCES&lt;/strong&gt;&amp;nbsp;, then you wait for&amp;nbsp;&lt;strong&gt;BLE_GATTS_EVT_HVN_TX_COMPLETE&lt;/strong&gt;&amp;nbsp; event, and continue calling&amp;nbsp;sd_ble_gatts_hvx(). You can read the value return in the&amp;nbsp;&lt;strong&gt;&amp;nbsp;BLE_GATTS_EVT_HVN_TX_COMPLETE&amp;nbsp;&lt;/strong&gt;to know how many&amp;nbsp;sd_ble_gatts_hvx() you should call. Or you can just simply call that function until you receive&amp;nbsp;&lt;strong&gt;NRF_ERROR_RESOURCES. &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>