<?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>Backoff mechanism for reliable mesh messages</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/30210/backoff-mechanism-for-reliable-mesh-messages</link><description>Hi, 
 I have a question about the time period being used as waiting time before sending a reliable message is retried, this until an ACK is received or the timeout is reached (minimal 30 s). According to the standard, this is &amp;quot;application specific&amp;quot;. From</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 11 Apr 2018 14:57:55 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/30210/backoff-mechanism-for-reliable-mesh-messages" /><item><title>RE: Backoff mechanism for reliable mesh messages</title><link>https://devzone.nordicsemi.com/thread/127872?ContentTypeID=1</link><pubDate>Wed, 11 Apr 2018 14:57:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d0492c2b-a932-46f9-98d5-fc3d047deb3c</guid><dc:creator>Mathias</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;I recently found out that the standard defines this application specific timeout on the Access Layer. I then looked there for this functionality. I found these constants:&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/** Penalty in microseconds for each hop for a reliable message. */&lt;br /&gt;#define ACCESS_RELIABLE_HOP_PENALTY (MS_TO_US(BEARER_ADV_INT_DEFAULT_MS))&lt;br /&gt;/**&lt;br /&gt;&amp;nbsp;* Base interval in microseconds for a reliable message.&lt;br /&gt;&amp;nbsp;* I.e., the interval given TTL=0 and an unsegmented message.&lt;br /&gt;&amp;nbsp;*/&lt;br /&gt;#define ACCESS_RELIABLE_INTERVAL_DEFAULT (MS_TO_US(BEARER_ADV_INT_DEFAULT_MS) * 10)&lt;br /&gt;&lt;br /&gt;/** Back-off factor used to increase the interval for each retry. */&lt;br /&gt;#define ACCESS_RELIABLE_BACK_OFF_FACTOR (2)&lt;/p&gt;
&lt;p&gt;The first two explain the 280 ms interval, which comes from&amp;nbsp;ACCESS_RELIABLE_INTERVAL_DEFAULT + TTL * ACCESS_RELIABLE_HOP_PENALTY , where BEARER_ADV_INT_DEFAULT_MS is 20 ms and TTL is 4 in my case (default values), so this gives 200 ms + 80 ms = 280 ms. Because of the ACCESS_RELIABLE_BACK_OFF_FACTOR&amp;nbsp; being 2, each following retry the interval is doubles (*2) which is also the case in my measurements.&lt;/p&gt;
&lt;p&gt;I also found these methods in access_reliable.c which explain the rest:&lt;/p&gt;
&lt;p&gt;static uint32_t calculate_interval(const access_reliable_t * p_message)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uint8_t ttl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* The model handle should already been checked by the TX attempt. */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_MESH_ERROR_CHECK(access_model_publish_ttl_get(p_message-&amp;gt;model_handle, &amp;amp;ttl));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uint16_t length = access_utils_opcode_size_get(p_message-&amp;gt;message.opcode) + p_message-&amp;gt;message.length;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uint32_t interval = (ttl * ACCESS_RELIABLE_HOP_PENALTY) + ACCESS_RELIABLE_INTERVAL_DEFAULT;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NRF_MESH_UNSEG_PAYLOAD_SIZE_MAX &amp;lt; length)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; interval += ((length + (NRF_MESH_SEG_SIZE - 1))/ NRF_MESH_SEG_SIZE) * ACCESS_RELIABLE_SEGMENT_COUNT_PENALTY;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return interval;&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;static void reliable_timer_cb(timestamp_t timestamp, void * p_context)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_MESH_ASSERT(0 &amp;lt; m_reliable.active_count);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //__LOG(LOG_SRC_APP, LOG_LEVEL_INFO,&amp;nbsp; &amp;quot;RELIABLE TIMER CALLBACK\n&amp;quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; timestamp += ACCESS_RELIABLE_TIMEOUT_MARGIN; /* TODO: Divide by two? */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.next_timeout_index = ACCESS_RELIABLE_INDEX_INVALID;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (uint32_t i = 0; i &amp;lt; ACCESS_RELIABLE_TRANSFER_COUNT; ++i)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!m_reliable.pool[i].in_use)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; continue;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (TIMER_OLDER_THAN(m_reliable.pool[i].params.timeout, timestamp))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Remove first, in case a crazy user tries to reschedule it in the callback. */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.pool[i].in_use = false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.active_count--;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void * p_args;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_MESH_ERROR_CHECK(access_model_p_args_get(m_reliable.pool[i].params.model_handle, &amp;amp;p_args));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.pool[i].params.status_cb(m_reliable.pool[i].params.model_handle, p_args, ACCESS_RELIABLE_TRANSFER_TIMEOUT);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (TIMER_OLDER_THAN(m_reliable.pool[i].next_timeout, timestamp))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; uint32_t status = access_model_publish(m_reliable.pool[i].params.model_handle, &amp;amp;m_reliable.pool[i].params.message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.next_timeout_index = i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NRF_SUCCESS == status)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.pool[i].next_timeout += m_reliable.pool[i].interval;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.pool[i].interval *= ACCESS_RELIABLE_BACK_OFF_FACTOR;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (NRF_ERROR_NO_MEM == status)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* If there is no more memory available, we might as well cancel the rest and set&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * the timer to fire in ACCESS_RELIABLE_RETRY_DELAY. */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.pool[i].next_timeout += ACCESS_RELIABLE_RETRY_DELAY;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* This should have been caught by the first publish() call. */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_MESH_ASSERT(false);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (TIMER_OLDER_THAN(m_reliable.pool[i].params.timeout, m_reliable.pool[i].next_timeout))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Shift timeout forward. */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.pool[i].next_timeout = m_reliable.pool[i].params.timeout;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (ACCESS_RELIABLE_INDEX_INVALID == m_reliable.next_timeout_index ||&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TIMER_OLDER_THAN(m_reliable.pool[i].next_timeout,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.pool[m_reliable.next_timeout_index].next_timeout))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Keep track of the next firing timeout. */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.next_timeout_index = i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Setting the interval &amp;gt; 0 will reschedule the timer. */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (m_reliable.active_count &amp;gt; 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_MESH_ASSERT(m_reliable.next_timeout_index &amp;lt; ACCESS_RELIABLE_TRANSFER_COUNT);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; timestamp -= ACCESS_RELIABLE_TIMEOUT_MARGIN;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.timer.interval = TIMER_DIFF(m_reliable.pool[m_reliable.next_timeout_index].next_timeout, timestamp);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_reliable.timer.interval = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t fully understand why the transport layer also needs to define timeout configuration but I can see.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Backoff mechanism for reliable mesh messages</title><link>https://devzone.nordicsemi.com/thread/120887?ContentTypeID=1</link><pubDate>Wed, 14 Feb 2018 15:59:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6ce96a5b-d47c-4795-bce9-f79b1642cbd2</guid><dc:creator>Mathias</dc:creator><description>&lt;p&gt;Okay, thank you very much for the explanation.&lt;/p&gt;
&lt;p&gt;Kind regards, Mathias&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Backoff mechanism for reliable mesh messages</title><link>https://devzone.nordicsemi.com/thread/120115?ContentTypeID=1</link><pubDate>Wed, 07 Feb 2018 13:16:54 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7e2da174-1372-4e46-809c-223c67013c74</guid><dc:creator>tesc</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;The timeout is based on TTL, and the exact formulas can be read in mesh/core/src/transport.c:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static inline uint32_t rx_ack_timer_delay_get(uint8_t ttl)
{
    return m_trs_config.rx_ack_base_timeout + m_trs_config.rx_ack_per_hop_addition * ttl;
}

static inline uint32_t tx_retry_timer_delay_get(uint8_t ttl)
{
    return m_trs_config.tx_retry_base_timeout + m_trs_config.tx_retry_per_hop_addition * ttl;
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The other parameters used are set to default values provided in mesh/core/include/transport.h:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/** Default base RX acknowledgement timeout. */
#define TRANSPORT_SAR_RX_ACK_BASE_TIMEOUT_DEFAULT_US MS_TO_US(150)

/** Default per hop RX acknowledgement timeout addition. */
#define TRANSPORT_SAR_RX_ACK_PER_HOP_ADDITION_DEFAULT_US MS_TO_US(50)

/** Default base TX retry timeout. */
#define TRANSPORT_SAR_TX_RETRY_BASE_TIMEOUT_DEFAULT_US MS_TO_US(500)

/** Default per hop TX retry timeout addition. */
#define TRANSPORT_SAR_TX_RETRY_PER_HOP_ADDITION_DEFAULT_US MS_TO_US(50)&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;These values can also be changed runtime, using &lt;a href="http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.meshsdk.v1.0.1%2Fgroup__NRF__MESH__OPT.html&amp;amp;anchor=ga35b7c71bb4d757648a509a42f28d7669"&gt;nrf_mesh_opt_set()&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Regards,&lt;br /&gt;Terje&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>