LWM2M Client - Power Management/callback functions

Good day

I have noticed that when using a callback functions certain limitations exist.  For example, adding functions to the callback function will run into an error or a timeout.  Firstly, I wanted to ask what the limitations when using a callback function(specifically lwm2m ).  Secondly, I am using 

pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND);  and 
pm_device_action_run(uart_dev, PM_DEVICE_ACTION_RESUME);
to dynamically turn the UART on and off during the callback function.  I was able to switch the UART on but when I use pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND at the end of the function, the UART does not switch off despite the function returning a 0.  What could be the cause of this?  I am aware that these issues are rather specific and any advice would be worthwhile.
Kind regards,
Hassan
Parents
  • Hi Hassan,

    I would need additional information.

    Which NCS version do you use? Do you use lwm2m client sample? Have you modified the sample?

    I have noticed that when using a callback functions certain limitations exist.  For example, adding functions to the callback function will run into an error or a timeout.  Firstly, I wanted to ask what the limitations when using a callback function(specifically lwm2m ).

    Could you elaborate on this? What are you trying to achieve? Could you provide an example?

    I was able to switch the UART on but when I use pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND at the end of the function, the UART does not switch off despite the function returning a 0.  What could be the cause of this?

    Could you specify more precisely what is currently working and what is not working? Does RESUME work, but SUSPEND not? Could you describe/show where and how you use pm_device_action_run() in your code? What is expected behavior and what actually happens?

    Best regards,
    Dejan

  • Good day Dejan

    I am using the latest toolchain and am modifying the lwm2m client sample. I am using a temperature sensor via a UART to receive information using low power measures and publish onto a lwm2m servers.  As a result, I need to turn on and off the UART when a callback is initiated via the server.  Initially I had a problem whereby the UART wouldn't switch off even after pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND was used.  However now, the UART doesnt switch on in time and there callback will result in a timeout server side.  Ive noticed that adding long functions to this callback (or even a delay) will result in a timeout.  Which makes me wonder if this callback has limitations i'm not aware of.  Thank you in advance!

    Kind regards,

    Hassan

Reply
  • Good day Dejan

    I am using the latest toolchain and am modifying the lwm2m client sample. I am using a temperature sensor via a UART to receive information using low power measures and publish onto a lwm2m servers.  As a result, I need to turn on and off the UART when a callback is initiated via the server.  Initially I had a problem whereby the UART wouldn't switch off even after pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND was used.  However now, the UART doesnt switch on in time and there callback will result in a timeout server side.  Ive noticed that adding long functions to this callback (or even a delay) will result in a timeout.  Which makes me wonder if this callback has limitations i'm not aware of.  Thank you in advance!

    Kind regards,

    Hassan

Children
  • Hi Hassan,

    There is a configuration option CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME which specifies how often client sends "I am alive" messages to the server. If the value of this option is set to more than 60 seconds, this may eventually cause timeout. You can have a look at the note in additional configuration.

    Best regards,
    Dejan

  • Thank you for this! will definitely attempt using this.  Another issue I am having as well is  RAI. Using the XRAI commands around my code has been working fine. however, it looks like after the callback function is used, the modem is used again and therefore putting the command at the end of this function doesn't work.  Have you any suggestions for this?

    Kind regards,

    Hassan

  • Hi Hassan,

    Could you show code samples of both working and non-working case when you use XRAI? 

    Best regards,
    Dejan

  • Hello 

    Its from my understanding, that the command can be used dynamically (I may be wring) so I'm using it whenever the an event is triggered.  This way when an update is triggered the command is sent.  This part works fine.

    tatic void rd_client_event(struct lwm2m_ctx *client, enum lwm2m_rd_client_event client_event)
    {
    	k_mutex_lock(&lte_mutex, K_FOREVER);
    
    	if (client_state == LTE_OFFLINE &&
    	    client_event != LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED) {
    		LOG_DBG("Drop network event %d at LTE offline state", client_event);
    		k_mutex_unlock(&lte_mutex);
    		return;
    	}
       
    	UART_multiple_handler();
    	RAI_init();
    	
    	switch (client_event) {
    	case LWM2M_RD_CLIENT_EVENT_NONE:
    		/* do nothing */
    		k_mutex_unlock(&lte_mutex);
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE:
    		LOG_DBG("Bootstrap registration failure!");
    		state_trigger_and_unlock(NETWORK_ERROR);
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_COMPLETE:
    		LOG_DBG("Bootstrap registration complete");
    		update_session_lifetime = true;
    		state_trigger_and_unlock(BOOTSTRAP);
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_TRANSFER_COMPLETE:
    		LOG_DBG("Bootstrap transfer complete");
    		k_mutex_unlock(&lte_mutex);
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE:
    		LOG_WRN("Registration failure!");
    		state_trigger_and_unlock(NETWORK_ERROR);
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE:
    		LOG_DBG("Registration complete");
    		state_trigger_and_unlock(CONNECTED);
    		RAI_init();
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT:
    		LOG_DBG("Registration update failure!");
    		state_trigger_and_unlock(NETWORK_ERROR);
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE:
    	    
    		LOG_DBG("Registration update complete");
    		state_trigger_and_unlock(CONNECTED);
    		RAI_init();
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE:
    		LOG_DBG("Deregister failure!");
    		reconnect = true;
    		state_trigger_and_unlock(NETWORK_ERROR);
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_DISCONNECT:
    		LOG_DBG("Disconnected");
    		state_set_and_unlock(START);
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF:
    		LOG_DBG("Queue mode RX window closed");
    		if (IS_ENABLED(CONFIG_LWM2M_CLIENT_UTILS_RAI)) {
    			lwm2m_rai_last();
    		}
    		k_mutex_unlock(&lte_mutex);
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED:
    		LOG_DBG("LwM2M engine suspended");
    		k_mutex_unlock(&lte_mutex);
    		break;
    
    	case LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR:
    		LOG_ERR("LwM2M engine reported a network error.");
    		reconnect = true;
    		state_trigger_and_unlock(NETWORK_ERROR);
    		break;
    	}
    }
    
    void RAI_init()
    {
    	// RAI Setup
    	//****************************//
    	static char response[200] = { 0 };
    	response[0] = '\0';
    
    	 k_sleep(K_MSEC(100));
    	nrf_modem_at_cmd(response, sizeof(response), "AT%%XRAI=3");
    	k_sleep(K_MSEC(100));
    	
    	LOG_WRN("RAI RESPONSE: %d",response );
        // // *****************************
    
    
    }

    However, when I do the same thing at the end of the callback function i don't get the same result.  It seems as though the modem is used immediately after the indication is sent (Some code was redacted)

    static void *read_cb(uint16_t obj_inst_id, uint16_t res_id, uint16_t res_inst_id, size_t *data_len)
    {
    	
    	uart_enable();
    		int c, d;
       
     
    
    
    	LOG_WRN("IN CUSTOM READ_CB");
    	LOG_WRN("obj_inst_id: %d", obj_inst_id);
    	if (obj_inst_id != 1) {
    		*data_len = 0;
    		return NULL;
    	}
    
    	
    
    	int err = lwm2m_engine_set_float("3300/1/5700", &sensor_value);
    	
    	
    
    	LOG_WRN("sensor value string: %d", err);
    	LOG_WRN("sensor value string: %s", numC);
    	LOG_WRN("sensor value double: %f", sensor_value);
    	
    
    	
    
    	
    	
    
    
    	if (err) {
    		LOG_ERR("Could not set custom sensor value: %d", err);
    		*data_len = 0;
    		return NULL;
    	}
    	*data_len = sizeof(sensor_value);
    	
    	RAI_init();
    	return &sensor_value;
    
       
    	
    		
    	}
    	else if(ret<0)
    	{
    		sensor_value = 0;
    		 RAI_init();
    		return &sensor_value;
    		
    
    	}
    	
    	
    }

    Do you have any suggestions of where to add the XRAI command to get the same result with the callback function?

  • Hi,

    Which modem firmware version and SDK do you use?

    If you use modem firmware v1.3.x and NCS v2.2.0, you could have a look at additional configuration in LwM2M Client Utils.

    Best regards,
    Dejan

Related