@@ -89,6 +89,15 @@ struct bt_mesh_net bt_mesh = {
8989 .local_queue = SYS_SLIST_STATIC_INIT (& bt_mesh .local_queue ),
9090};
9191
92+ /* Mesh Profile Specification 3.10.6
93+ * The node shall not execute more than one IV Index Recovery within a period of
94+ * 192 hours.
95+ *
96+ * Mark that the IV Index Recovery has been done to prevent two recoveries to be
97+ * done before a normal IV Index update has been completed within 96h+96h.
98+ */
99+ static bool ivi_was_recovered ;
100+
92101NET_BUF_POOL_DEFINE (loopback_buf_pool , CONFIG_BT_MESH_LOOPBACK_BUFS ,
93102 LOOPBACK_MAX_PDU_LEN , LOOPBACK_USER_DATA_SIZE , NULL );
94103
@@ -257,24 +266,24 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update)
257266 return false;
258267 }
259268
260- if (iv_index > bt_mesh .iv_index + 1 ) {
269+ if ((iv_index > bt_mesh .iv_index + 1 ) ||
270+ (iv_index == bt_mesh .iv_index + 1 && !iv_update )) {
271+ if (ivi_was_recovered ) {
272+ BT_ERR ("IV Index Recovery before minimum delay" );
273+ return false;
274+ }
275+ /* The Mesh profile specification allows to initiate an
276+ * IV Index Recovery procedure if previous IV update has
277+ * been missed. This allows the node to remain
278+ * functional.
279+ */
261280 BT_WARN ("Performing IV Index Recovery" );
281+ ivi_was_recovered = true;
262282 bt_mesh_rpl_clear ();
263283 bt_mesh .iv_index = iv_index ;
264284 bt_mesh .seq = 0U ;
265285 goto do_update ;
266286 }
267-
268- if (iv_index == bt_mesh .iv_index + 1 && !iv_update ) {
269- BT_WARN ("Ignoring new index in normal mode" );
270- return false;
271- }
272-
273- if (!iv_update ) {
274- /* Nothing to do */
275- BT_DBG ("Already in Normal state" );
276- return false;
277- }
278287 }
279288
280289 if (!(IS_ENABLED (CONFIG_BT_MESH_IV_UPDATE_TEST ) &&
@@ -292,21 +301,22 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update)
292301 return false;
293302 }
294303
295- do_update :
296- atomic_set_bit_to (bt_mesh .flags , BT_MESH_IVU_IN_PROGRESS , iv_update );
297- bt_mesh .ivu_duration = 0U ;
298-
299304 if (iv_update ) {
300305 bt_mesh .iv_index = iv_index ;
301306 BT_DBG ("IV Update state entered. New index 0x%08x" ,
302307 bt_mesh .iv_index );
303308
304309 bt_mesh_rpl_reset ();
310+ ivi_was_recovered = false;
305311 } else {
306312 BT_DBG ("Normal mode entered" );
307313 bt_mesh .seq = 0U ;
308314 }
309315
316+ do_update :
317+ atomic_set_bit_to (bt_mesh .flags , BT_MESH_IVU_IN_PROGRESS , iv_update );
318+ bt_mesh .ivu_duration = 0U ;
319+
310320 k_work_reschedule (& bt_mesh .ivu_timer , BT_MESH_IVU_TIMEOUT );
311321
312322 /* Notify other modules */
0 commit comments