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

Callback function not being called. Publishing to Group

I am currently publishing messages to a group of servers on a 10 second interval. This works well for a while but after a few minutes some of the nodes stop handling the message. They receive the message but do not call the callback function in the main. I have traced the problem to the function below. The if condition stops becoming true and thus the onoff_set_cb doesn't get called allowing me to update the value in the main. I believe it has something to do with the delay and transition time as they are not becoming zero causing the if condition to be false. When I print out the delay and remaining time they both stay at 50 and 100 and never become zero.  If I force the condition to become true(like in the code below) I never have problems with the nodes not handling the message. I am also having the same problem when using the level client and server.  I attached a screen shot of the debugger from the level client node. notice how it gets an acknowledgment back but some of the nodes aren't being set to the correct level. 

I am using acknowledged messages and I am receiving a status message back from the server nodes

I am using mesh sdk 3.0.0 and stock sdk 15.2

static void onoff_state_value_update(app_onoff_server_t * p_server)
{
    /* Requirement: If delay and transition time is zero, current state changes to the target state. */
    if ((p_server->state.delay_ms == 0 && p_server->state.remaining_time_ms == 0) ||
    /* Requirement: If current state is 0 (checked earlier) and target state is 1, current state value changes
     * to the target state value immediately after the delay.
     */
        (p_server->state.delay_ms == 0 && p_server->state.target_onoff == 1)||true)
    {
        p_server->state.present_onoff = p_server->state.target_onoff;

        generic_onoff_status_params_t status_params;
        status_params.present_on_off = p_server->state.present_onoff;
        status_params.target_on_off = p_server->state.target_onoff;
        status_params.remaining_time_ms = p_server->state.remaining_time_ms;
        (void) generic_onoff_server_status_publish(&p_server->server, &status_params);

        if (!p_server->value_updated)
        {
            p_server->onoff_set_cb(p_server, p_server->state.present_onoff);
            p_server->value_updated = true;
        }
    }

    __LOG(LOG_SRC_APP, LOG_LEVEL_DBG1, "cur onoff: %d  target: %d  delay: %d ms  remaining time: %d ms\n",
          p_server->state.present_onoff, p_server->state.target_onoff, p_server->state.delay_ms, p_server->state.remaining_time_ms);
}





Parents
  • Hi,

    Did you see this behavior with an unmodified example from the SDK? If so, which one, and if not, can you provide a project that shows the issue? It would be good to have a way to reproduce this, in order to investigate what might be the problem.

    Regards,
    Terje

  • Sorry for the long pause on this topic. It does happen on the unmodified dimming server example from the SDK. I started debugging the FSM and found where it is happening. As soon as transition_index@@@@ is printed out the callback function in the main stops being called and the FSM slows down. Again this is happening when the server receives a bunch of messages in a short time about 30 over 8 seconds. You could probably reproduce by making a loop that publishes a generic_level over a set interval. 

    Heres another screen shot from the stock Dimming Server indicating when the LED stops responding.

    P.S. After waiting for a minute or so it starts working again.

  • Hi,

    No problem with the pause.

    Thank you for the additional information.

    There are some known issues in examples\common\src\app_level.c, some of which might explain issues like the one you are seeing. See Multiple issues with app_level.c. For the issues listed in that post, 1 to 4 is already fixed and will be part of next nRF5 SDK for Mesh release. 5 is something we do not currently plan to implement (i.e. you must do that yourself if you want that behavior.) The fixes (all of them in app_level.c) are as follows:

    Lines 163-169:
        FSM_TRANSITION(E_DELTA_SET,       FSM_OTHERWISE,      A_TRANSITION_COMPLETE,S_IDLE),
        FSM_TRANSITION(E_MOVE_SET,        G_SET_DELAY,        A_DELAY_START,        S_IN_DELAY),
        FSM_TRANSITION(E_MOVE_SET,        G_SET_TRANSITION,   A_TRANSITION_START,   S_IN_TRANSITION),
    -    FSM_TRANSITION(E_MOVE_SET,        FSM_OTHERWISE,      FSM_NO_ACTION,        S_IDLE)
    +    FSM_TRANSITION(E_MOVE_SET,        FSM_OTHERWISE,      A_TRANSITION_COMPLETE,S_IDLE)
    };
    
    #if FSM_DEBUG
    
    Lines 320-326:
        model_timer_abort(&p_server->timer);
        p_server->state.transition_time_ms = 0;
    
    -    p_server->state.present_level = p_server->state.target_level;
    +    if (p_server->state.transition_type != TRANSITION_MOVE_SET)
    +    {
    +        p_server->state.present_level = p_server->state.target_level;
    +    }
    
        generic_level_status_params_t status_params;
        status_params.present_level = p_server->state.present_level;
    
    Lines 346-354:
        {
            /* Requirement: If transition time is not within valid range, do not start the transition. */
            case TRANSITION_SET:
    -            return (p_server->state.transition_time_ms > 0 && p_server->state.params.move.required_move != 0);
            case TRANSITION_DELTA_SET:
    -            return (p_server->state.transition_time_ms > 0 && p_server->state.params.set.required_delta != 0);
    +            return (p_server->state.transition_time_ms > 0 &&
    +                    p_server->state.transition_time_ms != MODEL_TRANSITION_TIME_UNKNOWN &&
    +                    p_server->state.params.set.required_delta != 0);
    
            /* Requirement: If transition time is not within valid range, or given move level (delta level)
            is zero, do not start the transition. */
    
    Lines 544-551:
            {
                p_server->state.transition_time_ms = *p_server->p_dtt_ms;
            }
    -
    -        p_server->state.target_level = p_server->state.present_level;
        }
        else
        {

    If the above does not solve the problem, or if you see any issues with the fix, please let us know and we will look further into it.

    Regards,
    Terje

Reply
  • Hi,

    No problem with the pause.

    Thank you for the additional information.

    There are some known issues in examples\common\src\app_level.c, some of which might explain issues like the one you are seeing. See Multiple issues with app_level.c. For the issues listed in that post, 1 to 4 is already fixed and will be part of next nRF5 SDK for Mesh release. 5 is something we do not currently plan to implement (i.e. you must do that yourself if you want that behavior.) The fixes (all of them in app_level.c) are as follows:

    Lines 163-169:
        FSM_TRANSITION(E_DELTA_SET,       FSM_OTHERWISE,      A_TRANSITION_COMPLETE,S_IDLE),
        FSM_TRANSITION(E_MOVE_SET,        G_SET_DELAY,        A_DELAY_START,        S_IN_DELAY),
        FSM_TRANSITION(E_MOVE_SET,        G_SET_TRANSITION,   A_TRANSITION_START,   S_IN_TRANSITION),
    -    FSM_TRANSITION(E_MOVE_SET,        FSM_OTHERWISE,      FSM_NO_ACTION,        S_IDLE)
    +    FSM_TRANSITION(E_MOVE_SET,        FSM_OTHERWISE,      A_TRANSITION_COMPLETE,S_IDLE)
    };
    
    #if FSM_DEBUG
    
    Lines 320-326:
        model_timer_abort(&p_server->timer);
        p_server->state.transition_time_ms = 0;
    
    -    p_server->state.present_level = p_server->state.target_level;
    +    if (p_server->state.transition_type != TRANSITION_MOVE_SET)
    +    {
    +        p_server->state.present_level = p_server->state.target_level;
    +    }
    
        generic_level_status_params_t status_params;
        status_params.present_level = p_server->state.present_level;
    
    Lines 346-354:
        {
            /* Requirement: If transition time is not within valid range, do not start the transition. */
            case TRANSITION_SET:
    -            return (p_server->state.transition_time_ms > 0 && p_server->state.params.move.required_move != 0);
            case TRANSITION_DELTA_SET:
    -            return (p_server->state.transition_time_ms > 0 && p_server->state.params.set.required_delta != 0);
    +            return (p_server->state.transition_time_ms > 0 &&
    +                    p_server->state.transition_time_ms != MODEL_TRANSITION_TIME_UNKNOWN &&
    +                    p_server->state.params.set.required_delta != 0);
    
            /* Requirement: If transition time is not within valid range, or given move level (delta level)
            is zero, do not start the transition. */
    
    Lines 544-551:
            {
                p_server->state.transition_time_ms = *p_server->p_dtt_ms;
            }
    -
    -        p_server->state.target_level = p_server->state.present_level;
        }
        else
        {

    If the above does not solve the problem, or if you see any issues with the fix, please let us know and we will look further into it.

    Regards,
    Terje

Children
Related