publish and subscribe address set and get function not working

Hello 

I try to write functions to modify the publish and the subscribe addresses.
Unfortunately not all is working, attached you will find my code.

Problems:


1.pubish set function:

I can't set the address back to 0 (unassigned).


2.subscribe get function
give me sometimes wrong addresses back when the address is not set 0

3. subscribe set function
sometimes i can't set a subscribe address

kind regards 

Michael

/**
 * get the publish address back
 *
 * @return publish address
 */
uint16_t common_ble_mesh_init_pub_addr_get(access_model_handle_t model)
{
	uint32_t status = NRF_SUCCESS;
	dsm_handle_t publish_address;

    if(model == NULL)   return 0;

	status = access_model_publish_address_get(model, &publish_address);

	if (status || publish_address == DSM_HANDLE_INVALID)
	{
		return 0;
	}

	nrf_mesh_address_t dst_address = {.value = 0};
	status = dsm_address_get(publish_address, &dst_address);

	if (status)
	{
		//printf("get pub address error %lu", status);
		return 0;
	}

	return dst_address.value;
}

/**
 * get the first subscribe address back
 *
 * @return subscribe address
 */
uint16_t common_ble_mesh_init_sub_addr_get(access_model_handle_t model)
{
	uint32_t status = NRF_SUCCESS;
	dsm_handle_t subscribe_address;
	uint16_t count = 1;

    if(model == NULL)   return 0;

	status = access_model_subscriptions_get(model, &subscribe_address, &count);

	if (status || subscribe_address == DSM_HANDLE_INVALID)
	{
		return 0;
	}

	nrf_mesh_address_t dst_address = {.value = 0};
	status = dsm_address_get(subscribe_address, &dst_address);

	if (status)
	{
		//printf("get sub address error %lu", status);
		return 0;
	}

	return dst_address.value;
}

/**
 * Set the publish address
 *
 * @param model
 * @param publish address
 *
 */
void common_ble_mesh_init_pub_addr_set(access_model_handle_t model, uint16_t pub_address)
{
    uint32_t err_code = NRF_SUCCESS;
    dsm_handle_t publish_address_handle;

    if(model == NULL)   return;

    if(pub_address == 0)
    {   // clear address
        err_code =  access_model_publish_address_get(model, &publish_address_handle);
        err_code |= dsm_address_publish_remove(publish_address_handle);
    }
    else
    {   // set address  
        err_code =  dsm_address_publish_add(pub_address, &publish_address_handle);
    	err_code |= access_model_publish_address_set(model, publish_address_handle);
    }

	if (err_code)
	{
		printf("model publish address set error %lu\r\n", err_code);
	}
   
}

/**
 * Set the subscribe address
 *
 * @param model
 * @param publish address
 *
 */
void common_ble_mesh_init_sub_addr_set(access_model_handle_t model, uint16_t sub_address)
{
    uint32_t err_code = NRF_SUCCESS;
    uint16_t count = 1;

    if(model == NULL)   return;

    dsm_handle_t subscription_address_handle;

    if(sub_address == 0)
    {
        err_code = access_model_subscriptions_get(model, &subscription_address_handle, &count);
        err_code |= access_model_subscription_remove(model, subscription_address_handle);
    }
    else
    {   // remove old address
        err_code = access_model_subscriptions_get(model, &subscription_address_handle, &count);
        err_code |= access_model_subscription_remove(model, subscription_address_handle);
        // Set address
        err_code = dsm_address_subscription_add(sub_address, &subscription_address_handle);
        err_code |= access_model_subscription_add(model, subscription_address_handle);
    }

	if (err_code)
	{
		printf("model publish address set error %lu\r\n", err_code);
	} 
}

Parents
  • Hi,

    1.pubish set function:

    I can't set the address back to 0 (unassigned).

    What happens when you try, do you get an error value, does it silently not work, or other?

    2.subscribe get function
    give me sometimes wrong addresses back when the address is not set 0

    I suggest initializing subscribe_address to DSM_HANDLE_INVALID before the call to access_model_subscriptions_get(), so that it will not contain a bogus value when the number of handles written by access_model_subscriptions_get() is 0, and instead of checking for DSM_HANDLE_INVALID after the call to access_model_subscriptions_get(), to check if 0 == count instead.

    uint16_t common_ble_mesh_init_sub_addr_get(access_model_handle_t model)
    {
    	uint32_t status = NRF_SUCCESS;
    	dsm_handle_t subscribe_address = DSM_HANDLE_INVALID;
    	uint16_t count = 1;
    
        if(model == NULL)   return 0;
    
    	status = access_model_subscriptions_get(model, &subscribe_address, &count);
    
    	if (status || subscribe_address == DSM_HANDLE_INVALID || 0 == count)
    	{
    		return 0;
    	}
    (...)

    3. subscribe set function
    sometimes i can't set a subscribe address

    What happens when you try, do you get an error value, does it silently not work, or other?

    In general I recommend adding ERROR_CHECK() around error return values, as is done throughout the mesh SDK libraries and examples. It will call the app error handler on non-NRF_SUCCESS values, so you get the error code and location for debugging. If there are return values that you can handle programmatically or safely ignore, then check for those and use ERROR_CHECK on the value otherwise.

    Regards,
    Terje

  • Hi

    1. I don't get a error value.
    When i added a publish address (eg. 0xC001) only to one model it is possible to clear the value again.
    As soon as i publish the same address to different models i can't remove them anymore.

    2. With your modification the problem is solved.

    3. I can't reproduce the issue again. Maybe it was some mistake from my side.

    regards,

    Michael

Reply Children
  • Hi,

    For 1, depending on how the publish address was set, there might be some internal state not being cleared up, or there might be conflict with already scheduled publications. You should consider access_model_publication_stop() for your use case, which cleans up both dsm and internal access layer state. (Removing the public address without stopping poublications may lead to other errors, but access_model_publication_stop() makes sure to put the device in a state where publicataions will not be attempted.)

    Please note that for normal configuration, adding and removing publish addresses etc. is done through the configuration server model on the node, from a provisioner. Use of functions such as access_model_publish_address_set() is for when you want the device to auto-configure without the need of configuring it from a provisioner. Further, those functions are considered to be an internal API, hence why they may be difficult to use (and lead to undefined or bad states if used incorrectly.)

    Regards,
    Terje

Related