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

Periodic messages from server to client in Light_switch example

Hi guys,

I am trying to modify Light switch example. My goal is to create a mesh network to transfer data from server to client periodically. So far, what I have done is to create a timer in server and set it in repeated mode. When I send message on from client to server, it starts the timer and start to call the function: app_onoff_status_publish(&m_onoff_server_0); 

However, when I log this function access_model_publish(); which is the function to actually send the status data, it returns 7, which is invalid params? 

Here is my code in main.c in sever side: 

APP_TIMER_DEF(timer_id);

static void timer_handler(void *p_context)
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "handler!\r\n");
	app_onoff_status_publish(&m_onoff_server_0);
}
static void timers_create()
{
    ret_code_t err_code;

	// timeout_id :
	err_code = app_timer_create(&timer_id, APP_TIMER_MODE_REPEATED, timer_handler);
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "app_timer_create error: %d\r\n", err_code);
}
// END ---------------------------------------

static void timer_start(uint16_t time)
{
    ret_code_t err_code;
	err_code = app_timer_start(timer_id, APP_TIMER_TICKS(time), NULL);
     __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "app_timer_start error: %d\r\n", err_code);
}

static void timer_stop()
{
	app_timer_stop(timer_id);
}

/* Callback for updating the hardware state */
static void app_onoff_server_set_cb(const app_onoff_server_t * p_server, bool onoff)
{
    /* Resolve the server instance here if required, this example uses only 1 instance. */

    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Setting GPIO value: %d\n", onoff)

    hal_led_pin_set(ONOFF_SERVER_0_LED, onoff);
    if(onoff)
    {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "start timer here!\r\n");
      timer_start(1000);
    }
    else
    {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "stop timer here!\r\n");
      timer_stop();
    }
}

And here is what I have in file generic_onoff_server.c, simply just log the function:

static uint32_t status_send(generic_onoff_server_t * p_server,
                            const access_message_rx_t * p_message,
                            const generic_onoff_status_params_t * p_params)
{
    uint32_t error_code;
    generic_onoff_status_msg_pkt_t msg_pkt;

    if (p_params->present_on_off > GENERIC_ONOFF_MAX ||
        p_params->target_on_off  > GENERIC_ONOFF_MAX ||
        p_params->remaining_time_ms > TRANSITION_TIME_STEP_10M_MAX)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    msg_pkt.present_on_off = p_params->present_on_off;
    if (p_params->remaining_time_ms > 0)
    {
        msg_pkt.target_on_off = p_params->target_on_off;
        msg_pkt.remaining_time = model_transition_time_encode(p_params->remaining_time_ms);
    }

    access_message_tx_t reply =
    {
        .opcode = ACCESS_OPCODE_SIG(GENERIC_ONOFF_OPCODE_STATUS),
        .p_buffer = (const uint8_t *) &msg_pkt,
        .length = p_params->remaining_time_ms > 0 ? GENERIC_ONOFF_STATUS_MAXLEN : GENERIC_ONOFF_STATUS_MINLEN,
        .force_segmented = p_server->settings.force_segmented,
        .transmic_size = p_server->settings.transmic_size
    };

    if (p_message == NULL)
    {
        error_code = access_model_publish(p_server->model_handle, &reply);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "access_model_publish error_code: %d\n", error_code);
        return error_code;
    }
    else
    {
        error_code = access_model_publish(p_server->model_handle, &reply);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "access_model_publish error_code: %d\n", error_code);
        return error_code;
    }
}

And here is the result: 

And nothing have been received from the client side. 

How can I fix this?

Thank you very much guys. 

Parents
  • Hi,

    Have you done the configuration correctly? From the documentation, you get NRF_ERROR_INVALID_PARAM if model is not bound to appkey, publish address not set or wrong opcode format.

  • Hi, 

    Clearly, the opcode is GENERIC_ONOFF_OPCODE_STATUS in function status_send() above. I configured this mesh using nrfMesh on Phone base on this video on youtube https://www.youtube.com/watch?v=XthbU9NP0Yg. The thing is when it return as a replymessege to set acknowledge messege from client, it worked fine (like in example), but when it return as status messege, when I set timer so it return every second, it's not worked.

  • Turn out, I did not set the publish address for the server side, only for the client side. :( so stupid

  • hi, I want do the same modify as your's . But my app_timer is not working ,i don't kow why .

    APP_TIMER_DEF(my_timer_id); 
    
    static void timerout_handler_mine(void *p_context)
    {
    	__LOG(LOG_SRC_APP,LOG_LEVEL_INFO,"time is done \n");	
    //	hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_START);
    }
    
    int main(void)
    {
    	ret_code_t error_code;
    	
    	__LOG_INIT(LOG_SRC_APP | LOG_SRC_ACCESS | LOG_SRC_BEARER, LOG_LEVEL_INFO, LOG_CALLBACK_DEFAULT);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh Light Switch Server Demo Modify -----\n");
    
        ERROR_CHECK(app_timer_init());
        hal_leds_init();
    	ERROR_CHECK(hal_buttons_init(button_event_handler));
    
    /* Temperature init */
        nrf_temp_init();
        temp_read();
    
        ble_stack_init();
        gap_params_init();
        conn_params_init();
        mesh_init();
    
    	start();
    	
    	/* App Timer test */
    	error_code = app_timer_create(&my_timer_id, APP_TIMER_MODE_REPEATED, timerout_handler_mine);
    	__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "tiemr create error	= %d \n",error_code);
    
    
    	error_code = app_timer_start(&my_timer_id,APP_TIMER_TICKS(800),  NULL);
    	__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "tiemr start error  = %d \n",error_code);
    
    /***/
    //	  initialize();
    
        for (;;)
        {
            (void)sd_app_evt_wait();
        }
    }
    

    Here is my code. Can you point somewhere wrong in my code? Or I missed init?

  • In order to use timer, you have to init it witth the timer create function: 

    app_timer_create();

    and then start it with the function: 

    app_timer_start();
    That's all :)
Reply Children
No Data
Related