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 :)
  • Hi Hust,

    i have this problem also, i can send message from light_switch_client to server ok, then server send reply to client using status_send(), and this call "access_model_publish(p_server->model_handle, &reply);" return SUCCESS but server side does not receives any thing.

    I setup pub/sub as below:

    Server publish to 0xC000

    Client subscribe to 0xC000

    I try to add callback function in client code to capture rx_event 'nrf_mesh_evt_handler_add(..) but never receive any message from server. That's strange!

    My goal is server will send reply to client when he receive from client.

    Can you give me any suggest!

    Thanks in advance!

Reply
  • Hi Hust,

    i have this problem also, i can send message from light_switch_client to server ok, then server send reply to client using status_send(), and this call "access_model_publish(p_server->model_handle, &reply);" return SUCCESS but server side does not receives any thing.

    I setup pub/sub as below:

    Server publish to 0xC000

    Client subscribe to 0xC000

    I try to add callback function in client code to capture rx_event 'nrf_mesh_evt_handler_add(..) but never receive any message from server. That's strange!

    My goal is server will send reply to client when he receive from client.

    Can you give me any suggest!

    Thanks in advance!

Children
No Data
Related