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

Parents
  • Hi Thomas, 

    I'm not sure what could be wrong with your code. But you can refer to handle_config_model_publication_set() in config_server.c where we replace one publication address with another. 

    Another option if you have a lot of message that you need to change the destination address dynamically, you can think of using the transport layer directly. Skipping the DSM. Basically you need to write something similar to packet_tx() and use nrf_mesh_packet_send() to send a mesh packet directly. 

Reply
  • Hi Thomas, 

    I'm not sure what could be wrong with your code. But you can refer to handle_config_model_publication_set() in config_server.c where we replace one publication address with another. 

    Another option if you have a lot of message that you need to change the destination address dynamically, you can think of using the transport layer directly. Skipping the DSM. Basically you need to write something similar to packet_tx() and use nrf_mesh_packet_send() to send a mesh packet directly. 

Children
Related