espressif / esp-nimble

A fork of NimBLE stack, for use with ESP32 and ESP-IDF
Apache License 2.0
76 stars 49 forks source link

After joining network that has its IV one higher than own, ignores network #51

Closed JesseRiemens closed 1 year ago

JesseRiemens commented 1 year ago

net.c Line 232, states that when the IV of the network is one further than its current IV, it will ignore the messages and will not update to the newer IV. Only when the IV of the network is more than one higher, it will update to the newer IV.


if (iv_index > bt_mesh.iv_index + 1)
{
  BT_WARN("Performing IV Index Recovery");
  bt_mesh_rpl_clear();
  bt_mesh.iv_index = iv_index;
  bt_mesh.seq = 0;
  goto do_update;
}

if (iv_index == bt_mesh.iv_index + 1 && !iv_update)
{
  BT_WARN("Ignoring new index in normal mode");
  return false;
}

That means that when a device has missed the IV update procedures, it will not be able to join the network again until the IV is updated once more.

This is not strictly compliant with what the mesh profile spec (by the Bluetooth SIG) states about this:

If a node in Normal Operation receives a Secure Network beacon with an IV index equal to the last known IV index+1 and the IV Update Flag set to 0, the node may update its IV without going to the IV Update in Progress state, or it may initiate an IV Index Recovery procedure (Section 3.10.6), or it may ignore the Secure Network beacon. The node makes the choice depending on the time since last IV update and the likelihood that the node has missed the Secure Network beacons with the IV update Flag set to 1.

Source: Mesh Profile - Bluetooth® Specification - Revision: v1.0.1 - page 132

Currently no choice is made, but it is alway ignored, according to the third option given. What should be done about this to make this compliant with the bluetooth spec?

A neater way to solve this is by always going into recovery mode, so a node doesn't 'fall off' the newtork.

JesseRiemens commented 1 year ago

Note: Upstream, this is done in the following way:

if ((iv_index > bt_mesh.iv_index + 1) ||
    (iv_index == bt_mesh.iv_index + 1 && !iv_update))
{
  if (ivi_was_recovered)
  {
    BT_ERR("IV Index Recovery before minimum delay");
    return false;
  }
  /* The Mesh profile specification allows to initiate an
   * IV Index Recovery procedure if previous IV update has
   * been missed. This allows the node to remain
   * functional.
   */
  BT_WARN("Performing IV Index Recovery");
  ivi_was_recovered = true;
  bt_mesh_rpl_clear();
  bt_mesh.iv_index = iv_index;
  bt_mesh.seq = 0;
  goto do_update;
}
rahult-github commented 1 year ago

Hi @JesseRiemens ,

ESP-IDF nimble codebase is currently synced to nimble-1.4.0-idf. We are internally working on syncing to latest codebase ( nimble-1.5.0 ) that upstream mynewt nimble currently points to. Once migration is done, the newer code would then be part of IDF.

Thanks, Rahul

rahult-github commented 1 year ago

Change is now available on master branch.