This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

GATT => Mesh gateway problem

Hi

I am running on a nRF52832 chip with following software stacks

  • Mesh SDK v3.1.0
  • nRF SDK v15.2.0
  • Softdevice v6.1.0


I am working on a use-case where I am processing some GATT messages. Sometimes I need to create a mesh message based upon the GATT message. The message contains a target mesh address. This address is either a unicast or a group address. I need to publish a message on a model handle to a specific target address.
What I am trying to do this basically this:
   status = access_model_publish_to(p_client->model_handle, &p_client->access_message.message, target_address);

Currently I am using the unacknowledged publish with:
      status = access_model_publish(p_client->model_handle, &p_client->access_message.message);

Just before creating and publishing the message I am using the following code to change the target address

static void publish_address_change(const access_model_handle_t model_handle, const uint16_t address)
{
    // Add and set new target
    dsm_handle_t publish_address_handle = DSM_HANDLE_INVALID;
    NRF_MESH_ERROR_CHECK(dsm_address_publish_add(actual_address, &publish_address_handle));
    NRF_MESH_ERROR_CHECK(access_model_publish_address_set(model_handle, publish_address_handle));
}

My code is based upon the Hung Bui's reply here: https://devzone.nordicsemi.com/f/nordic-q-a/35931/multiple-server-on-one-client---light-switch-demo

The code works well until the m_addresses array in device_state_manager.c have been filled up.
I can increase the size of the array with DSM_NONVIRTUAL_ADDR_MAX, but that only postpone the problem.

I have tried to delete the old address when I change to a new address. To accomplish this, I have the following code:

static void publish_address_change(const access_model_handle_t model_handle, const uint16_t address)
{
    // Convert GATT target address to mesh target address
    uint16_t actual_address = process_target_address(address);

    // Remove old publish address if one exists
    dsm_handle_t old_publish_address_handle = DSM_HANDLE_INVALID;
    if (access_model_publish_address_get(model_handle, &old_publish_address_handle) == NRF_SUCCESS)
    {
        nrf_mesh_address_t publish_address_stored = {0};
        if (dsm_address_get(old_publish_address_handle, &publish_address_stored) == NRF_SUCCESS &&
            publish_address_stored.value == address)
        {
            // No need to change publish address, return
            return;
        }
        else
        {
            dsm_address_publish_remove(old_publish_address_handle);
        }
    }

    // Add and set new target
    dsm_handle_t publish_address_handle = DSM_HANDLE_INVALID;
    NRF_MESH_ERROR_CHECK(dsm_address_publish_add(actual_address, &publish_address_handle));
    NRF_MESH_ERROR_CHECK(access_model_publish_address_set(model_handle, publish_address_handle));
}

Unfortunately, this doesn't work. In a test setup with 6 nodes they eventually end up in a state where. when turning power on and off, the dsm addresses and access_model handles go out of sync.

Specifically I get a mesh assert error when it tries to add an address handle that points to a 0x0000 address in dsm_address_publish_add_handle(dsm_handle_t address_handle)
This happens in mesh_stack_init -> access_flash_config_load

What am I doing wrong?

Is there a recommended way of implementing a gateway feature?

Thanks,

Thomas

Related