<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Server&amp;#39;s function to send message to client in Mesh 3.1</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/45517/server-s-function-to-send-message-to-client-in-mesh-3-1</link><description>Hello to everyone. 
 I&amp;#39;m working with Light_switch example for nRF52832 (PCA10040) and Mesh 3.1. I&amp;#39;m trying to modify the server example and to do that I need to know where (in the whole main.c code) is the part that send the server&amp;#39;s status to client</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 03 Apr 2019 17:12:32 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/45517/server-s-function-to-send-message-to-client-in-mesh-3-1" /><item><title>RE: Server's function to send message to client in Mesh 3.1</title><link>https://devzone.nordicsemi.com/thread/180093?ContentTypeID=1</link><pubDate>Wed, 03 Apr 2019 17:12:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a6f8af01-408c-4dfe-a420-cbd07f947b66</guid><dc:creator>JK0201</dc:creator><description>&lt;p&gt;Thank you a lot!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Server's function to send message to client in Mesh 3.1</title><link>https://devzone.nordicsemi.com/thread/179919?ContentTypeID=1</link><pubDate>Wed, 03 Apr 2019 09:24:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:db624a48-9331-42c3-bf85-d51b14f6cd39</guid><dc:creator>Mttrinh</dc:creator><description>&lt;p&gt;generic_onoff_server_status_publish() is the function that sends the status to client.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Server's function to send message to client in Mesh 3.1</title><link>https://devzone.nordicsemi.com/thread/179852?ContentTypeID=1</link><pubDate>Tue, 02 Apr 2019 19:27:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:be344754-faf6-4630-aefd-a9f0b2237df0</guid><dc:creator>JK0201</dc:creator><description>&lt;p&gt;Thank you for answer.&lt;br /&gt;I was working with your suggestion.&lt;pre class="ui-code" data-mode="c_cpp"&gt;#include &amp;quot;app_onoff.h&amp;quot;

#include &amp;lt;stdint.h&amp;gt;

#include &amp;quot;sdk_config.h&amp;quot;
#include &amp;quot;example_common.h&amp;quot;
#include &amp;quot;generic_onoff_server.h&amp;quot;

#include &amp;quot;log.h&amp;quot;
#include &amp;quot;app_timer.h&amp;quot;

/** This sample implementation shows how the model behavior requirements of Generic OnOff server can
 * be implemented.
 */

/* Forward declaration */
static void generic_onoff_state_get_cb(const generic_onoff_server_t * p_self,
                                       const access_message_rx_meta_t * p_meta,
                                       generic_onoff_status_params_t * p_out);
static void generic_onoff_state_set_cb(const generic_onoff_server_t * p_self,
                                       const access_message_rx_meta_t * p_meta,
                                       const generic_onoff_set_params_t * p_in,
                                       const model_transition_t * p_in_transition,
                                       generic_onoff_status_params_t * p_out);

const generic_onoff_server_callbacks_t onoff_srv_cbs =
{
    .onoff_cbs.set_cb = generic_onoff_state_set_cb,
    .onoff_cbs.get_cb = generic_onoff_state_get_cb
};

static void onoff_state_process_timing(app_onoff_server_t * p_server)
{
    uint32_t status = NRF_SUCCESS;

    (void) app_timer_stop(*p_server-&amp;gt;p_timer_id);

    /* Process timing requirements */
    if (p_server-&amp;gt;state.delay_ms != 0)
    {
        status = app_timer_start(*p_server-&amp;gt;p_timer_id, APP_TIMER_TICKS(p_server-&amp;gt;state.delay_ms), p_server);
    }
    else if (p_server-&amp;gt;state.remaining_time_ms != 0)
    {
        /* Note: We cannot use the full length of the app_timer, since RTC counter is 24 bit, and
        application needs to report the remaining time whenever GET message is received in the
        middle of the transition. Correctness of the reported value is limited to 100 ms at the
        highest resolution as defined in section 3.1.3 of Mesh Model Specification v1.0 */
        uint32_t app_timer_ticks = APP_TIMER_TICKS(p_server-&amp;gt;state.remaining_time_ms);
        if (app_timer_ticks &amp;gt; APP_TIMER_MAX_CNT_VAL)
        {
            status = app_timer_start(*p_server-&amp;gt;p_timer_id, APP_TIMER_MAX_CNT_VAL, p_server);
        }
        else if (app_timer_ticks &amp;gt;= APP_TIMER_MIN_TIMEOUT_TICKS)
        {
            status = app_timer_start(*p_server-&amp;gt;p_timer_id, APP_TIMER_TICKS(p_server-&amp;gt;state.remaining_time_ms), p_server);
        }
        else
        {
            status = app_timer_start(*p_server-&amp;gt;p_timer_id, APP_TIMER_MIN_TIMEOUT_TICKS, p_server);
        }
        p_server-&amp;gt;last_rtc_counter = app_timer_cnt_get();
    }

    if (status != NRF_SUCCESS)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR, &amp;quot;State transition timer error\n&amp;quot;);
    }
}

// 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-&amp;gt;state.delay_ms == 0 &amp;amp;&amp;amp; p_server-&amp;gt;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-&amp;gt;state.delay_ms == 0 &amp;amp;&amp;amp; p_server-&amp;gt;state.target_onoff == 1))
    {
        p_server-&amp;gt;state.present_onoff = p_server-&amp;gt;state.target_onoff;

        generic_onoff_status_params_t status_params;
        status_params.present_on_off = p_server-&amp;gt;state.present_onoff;
        status_params.target_on_off = p_server-&amp;gt;state.target_onoff;
        status_params.remaining_time_ms = p_server-&amp;gt;state.remaining_time_ms;
        (void) generic_onoff_server_status_publish(&amp;amp;p_server-&amp;gt;server, &amp;amp;status_params);

        if (!p_server-&amp;gt;value_updated)
        {
            p_server-&amp;gt;onoff_set_cb(p_server, p_server-&amp;gt;state.present_onoff);
            p_server-&amp;gt;value_updated = true;
        }
    }

    __LOG(LOG_SRC_APP, LOG_LEVEL_DBG1, &amp;quot;cur onoff: %d  target: %d  delay: %d ms  remaining time: %d ms\n&amp;quot;,
          p_server-&amp;gt;state.present_onoff, p_server-&amp;gt;state.target_onoff, p_server-&amp;gt;state.delay_ms, p_server-&amp;gt;state.remaining_time_ms);
}

static void onoff_state_timer_cb(void * p_context)
{
    app_onoff_server_t * p_server = (app_onoff_server_t *) p_context;

    /* Requirement: Process timing. Process the delay first (Non-zero delay will delay the required
     * state transition by the specified amount) and then the transition time.
     */
    if (p_server-&amp;gt;state.delay_ms != 0)
    {
        p_server-&amp;gt;state.delay_ms = 0;
        onoff_state_value_update(p_server);
    }
    else if (p_server-&amp;gt;state.remaining_time_ms != 0)
    {
        if (APP_TIMER_TICKS(p_server-&amp;gt;state.remaining_time_ms) &amp;gt; APP_TIMER_MAX_CNT_VAL)
        {
            p_server-&amp;gt;state.remaining_time_ms -= (APP_TIMER_MAX_CNT_VAL/APP_TIMER_CLOCK_FREQ);
        }
        else
        {
            p_server-&amp;gt;state.remaining_time_ms = 0;
            onoff_state_value_update(p_server);
        }
    }
    onoff_state_process_timing(p_server);
}


/***** Generic OnOff model interface callbacks *****/

static void generic_onoff_state_get_cb(const generic_onoff_server_t * p_self,
                                       const access_message_rx_meta_t * p_meta,
                                       generic_onoff_status_params_t * p_out)
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, &amp;quot;msg: GET \n&amp;quot;);

    app_onoff_server_t   * p_server = PARENT_BY_FIELD_GET(app_onoff_server_t, server, p_self);

    /* Requirement: Provide the current value of the OnOff state */
    p_server-&amp;gt;onoff_get_cb(p_server, &amp;amp;p_server-&amp;gt;state.present_onoff);
    p_out-&amp;gt;present_on_off = p_server-&amp;gt;state.present_onoff;
    p_out-&amp;gt;target_on_off = p_server-&amp;gt;state.target_onoff;

    /* Requirement: Always report remaining time */
    if (p_server-&amp;gt;state.remaining_time_ms &amp;gt; 0 &amp;amp;&amp;amp; p_server-&amp;gt;state.delay_ms == 0)
    {
        uint32_t delta = (1000ul * app_timer_cnt_diff_compute(app_timer_cnt_get(), p_server-&amp;gt;last_rtc_counter)) / APP_TIMER_CLOCK_FREQ;
        if (p_server-&amp;gt;state.remaining_time_ms &amp;gt;= delta &amp;amp;&amp;amp; delta &amp;gt; 0)
        {
            p_out-&amp;gt;remaining_time_ms = p_server-&amp;gt;state.remaining_time_ms - delta;
        }
        else
        {
            p_out-&amp;gt;remaining_time_ms = 0;
        }
    }
    else
    {
        p_out-&amp;gt;remaining_time_ms = p_server-&amp;gt;state.remaining_time_ms;
    }
}
// 1 ****************************************************************************
//*******************************************************************************
//*******************************************************************************
static void generic_onoff_state_set_cb(const generic_onoff_server_t * p_self,
                                       const access_message_rx_meta_t * p_meta,
                                       const generic_onoff_set_params_t * p_in,
                                       const model_transition_t * p_in_transition,
                                       generic_onoff_status_params_t * p_out)
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, &amp;quot;msg: SET: %d\n&amp;quot;, p_in-&amp;gt;on_off);

    app_onoff_server_t   * p_server = PARENT_BY_FIELD_GET(app_onoff_server_t, server, p_self);

    /* Update internal representation of OnOff value, process timing */
    p_server-&amp;gt;value_updated = false;
    p_server-&amp;gt;state.target_onoff = p_in-&amp;gt;on_off;
    if (p_in_transition == NULL)
    {
        p_server-&amp;gt;state.delay_ms = 0;
        p_server-&amp;gt;state.remaining_time_ms = 0;
    }
    else
    {
        p_server-&amp;gt;state.delay_ms = p_in_transition-&amp;gt;delay_ms;
        p_server-&amp;gt;state.remaining_time_ms = p_in_transition-&amp;gt;transition_time_ms;
    }

    onoff_state_value_update(p_server); //****send p_server to function****
    onoff_state_process_timing(p_server);

    /* Prepare response */
    if (p_out != NULL)
    {
        p_out-&amp;gt;present_on_off = p_server-&amp;gt;state.present_onoff;
        p_out-&amp;gt;target_on_off = p_server-&amp;gt;state.target_onoff;
        p_out-&amp;gt;remaining_time_ms = p_server-&amp;gt;state.remaining_time_ms;
    }
}


/***** Interface functions *****/

void app_onoff_status_publish(app_onoff_server_t * p_server)
{
    p_server-&amp;gt;onoff_get_cb(p_server, &amp;amp;p_server-&amp;gt;state.present_onoff);

    p_server-&amp;gt;state.target_onoff = p_server-&amp;gt;state.present_onoff;
    p_server-&amp;gt;state.delay_ms = 0;
    p_server-&amp;gt;state.remaining_time_ms = 0;
    (void) app_timer_stop(*p_server-&amp;gt;p_timer_id);

    generic_onoff_status_params_t status = {
                .present_on_off = p_server-&amp;gt;state.present_onoff,
                .target_on_off = p_server-&amp;gt;state.target_onoff,
                .remaining_time_ms = p_server-&amp;gt;state.remaining_time_ms
            };
    (void) generic_onoff_server_status_publish(&amp;amp;p_server-&amp;gt;server, &amp;amp;status);
}

uint32_t app_onoff_init(app_onoff_server_t * p_server, uint8_t element_index)
{
    uint32_t status = NRF_ERROR_INTERNAL;

    if (p_server == NULL)
    {
        return NRF_ERROR_NULL;
    }

    p_server-&amp;gt;server.settings.p_callbacks = &amp;amp;onoff_srv_cbs;
    if (p_server-&amp;gt;onoff_set_cb == NULL || p_server-&amp;gt;onoff_get_cb == NULL)
    {
        return NRF_ERROR_NULL;
    }

    status = generic_onoff_server_init(&amp;amp;p_server-&amp;gt;server, element_index);
    if (status == NRF_SUCCESS)
    {
        status = app_timer_create(p_server-&amp;gt;p_timer_id, APP_TIMER_MODE_SINGLE_SHOT,
                                  onoff_state_timer_cb);
    }

    return status;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I understand that, in app_onoff.c file, the generic_onoff_state_set_cb() function (// 1*** in code) calls the onoff_state_value_update() function (// 2*** in code), but there, in the second function, where is the exactly place where the function send or update the information that client receive and shows?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Server's function to send message to client in Mesh 3.1</title><link>https://devzone.nordicsemi.com/thread/179547?ContentTypeID=1</link><pubDate>Mon, 01 Apr 2019 14:36:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d01e1bb6-5d36-4d7a-9ad3-9dc49be2cef3</guid><dc:creator>Mttrinh</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Have a look inside the&amp;nbsp;generic_onoff_state_set_cb() -&amp;gt; onoff_state_value_update() in app_onoff.c&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>