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

How to to set a keep alive value of MQTT while eDRX is enabled in nRF9160?

I want to set a keep alive value of MQTT while eDRX is enabled, but it doesn't work well. Any advice?

Environment
- hardware: nRF9160 DK 0.8.2
- firmware: 0.7.0-29.alpha
- nrf ver: 0.4.0
- LTE-M
- eDRX enable
- mqtt_simple works fine with mosquitto MQTT broker
- project based on mqtt_simple
- antenna power is fine
- eDRX service is available here

AT+CEDRXS?
OK
AT+CEDRXS=1,4,"1000"

I added MQTT_KEEPALIVE param to Kconfig and CONF_MQTT_KEEPALIVE param to pro.conf
I've tested several conditions
[condition]
- CONFIG_LTE_EDRX_REQ_VALUE="0110" in prj.conf // 327.68 sec interval
CONF_MQTT_KEEPALIVE=300 in prj.conf
[result]
eDRX doesn't work properly. When I send a message to a MQTT broker, the DK receives it right after that. There should be a delay due to the eDRX.

[condition]
CONFIG_LTE_EDRX_REQ_VALUE="0110" in prj.conf // 327.68 sec interval
CONF_MQTT_KEEPALIVE=400 in prj.conf
[result]
The DK does not receive any message after 360sec followed by disconnection.

This is the whole project.

<Kconfig>
menu "MQTT simple sample"
config MQTT_PUB_TOPIC
	string "MQTT publish topic"
	default "my/publish/topic"

config MQTT_SUB_TOPIC
	string "MQTT subscribe topic"
	default "my/subscribe/topic"

config MQTT_CLIENT_ID
	string "MQTT Client ID"
	default "my-client-id"

config MQTT_BROKER_HOSTNAME
	string "MQTT broker hostname"
	default "iot.eclipse.org"

config MQTT_BROKER_PORT
	int "MQTT broker port"
	default 1883

config MQTT_MESSAGE_BUFFER_SIZE
	int ""
	default 128

config MQTT_PAYLOAD_BUFFER_SIZE
	int ""
	default 128

config MQTT_KEEPALIVE
	int ""
	default 60

endmenu

menu "Zephyr Kernel"
source "$ZEPHYR_BASE/Kconfig.zephyr"
endmenu

<prj.conf>

# General config
CONFIG_TEST_RANDOM_GENERATOR=y

# Networking
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y

# LTE link control
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_NETWORK_MODE_LTE_M=y
CONFIG_LTE_AUTO_INIT_AND_CONNECT=n
# CONFIG_LTE_EDRX_REQ_ACTT_TYPE="4"
CONFIG_LTE_EDRX_REQ=y
CONFIG_LTE_EDRX_REQ_VALUE="0110"
# 0100 81.92sec
# 0101 163.84sec
# 0110 327.68sec
# 0111 655.36sec

# LTE link control
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_AUTO_INIT_AND_CONNECT=n

# BSD library
CONFIG_BSD_LIBRARY=y

# AT Host
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_AT_HOST_LIBRARY=y

# MQTT
CONFIG_MQTT_LIB=y
CONFIG_MQTT_LIB_TLS=n

# Appliaction
CONFIG_MQTT_PUB_TOPIC="myPubTopic"
CONFIG_MQTT_SUB_TOPIC="mySubTopic"
CONFIG_MQTT_CLIENT_ID="myClientID"
CONFIG_MQTT_BROKER_HOSTNAME="xxxxxxxxxx.com"
CONFIG_MQTT_BROKER_PORT=1883
CONFIG_MQTT_KEEPALIVE=300 # ADD here

# Main thread
CONFIG_MAIN_THREAD_PRIORITY=7
CONFIG_MAIN_STACK_SIZE=4096

CONFIG_HEAP_MEM_POOL_SIZE=1024

<main.c>

#include <zephyr.h>
#include <stdio.h>
#include <uart.h>
#include <string.h>

#include <net/mqtt.h>
#include <net/socket.h>
#include <lte_lc.h>

#define MQTT_USERNAME "username"
#define MQTT_PASSWORD "password"
.
.
.

/**@brief Initialize the MQTT client structure
 */
static void client_init(struct mqtt_client *client)
{
	mqtt_client_init(client);

	broker_init();

    /* Add from here */
    static struct mqtt_utf8 password;
	static struct mqtt_utf8 user_name;

	password.utf8 = (u8_t *)MQTT_PASSWORD;
	password.size = strlen(MQTT_PASSWORD);
	user_name.utf8 = (u8_t *)MQTT_USERNAME;
	user_name.size = strlen(MQTT_USERNAME);
    /* to here */

	/* MQTT client configuration */
	client->broker = &broker;
	client->evt_cb = mqtt_evt_handler;
	client->client_id.utf8 = (u8_t *)CONFIG_MQTT_CLIENT_ID;
	client->client_id.size = strlen(CONFIG_MQTT_CLIENT_ID);
	client->password = &password; // Add here
	client->user_name = &user_name; // Add here
	client->protocol_version = MQTT_VERSION_3_1_0; // originally MQTT_VERSION_3_1_1

	/* MQTT buffers configuration */
	client->rx_buf = rx_buffer;
	client->rx_buf_size = sizeof(rx_buffer);
	client->tx_buf = tx_buffer;
	client->tx_buf_size = sizeof(tx_buffer);

	/* MQTT transport configuration */
	client->transport.type = MQTT_TRANSPORT_NON_SECURE;
}

.
.

void main(void)
{
	int err;

	printk("The MQTT simple sample started\n");

	modem_configure();

    /* ADD here */
    err = lte_lc_edrx_req(true);
    if (err) {
        printk("ERROR: set edrx %d\n", err);
        return;
    }
    /* ADD here */

	client_init(&client);

	err = mqtt_connect(&client);
	if (err != 0) {
		printk("ERROR: mqtt_connect %d\n", err);
		return;
	}

	err = fds_init(&client);
	if (err != 0) {
		printk("ERROR: fds_init %d\n", err);
		return;
	}

	while (1) {
		err = poll(&fds, 1, K_SECONDS(CONFIG_MQTT_KEEPALIVE)); 
		if (err < 0) {
			printk("ERROR: poll %d\n", errno);
			break;
		}

        err = mqtt_live(&client);
		if (err != 0) {
			printk("ERROR: mqtt_live %d\n", err);
			break;
		}

		if ((fds.revents & POLLIN) == POLLIN) {
			err = mqtt_input(&client); // if a publish event comes, mqtt_evt_handler is called here
			if (err != 0) {
				printk("ERROR: mqtt_input %d\n", err);
				break;
			}
		}

		if ((fds.revents & POLLERR) == POLLERR) {
			printk("POLLERR\n");
			break;
		}

		if ((fds.revents & POLLNVAL) == POLLNVAL) {
			printk("POLLNVAL\n");
			break;
		}
	}

}

This is a test condition.
Ideally, I want to set a longer keepalive value, like 1200(sec) to decrease power consumption.
- keep alive of MQTT: 1200 sec
- eDRX interval value: 655 sec

I have been struggling with this issue more than two weeks, but I don't really get the eDRX behavior. Any advice?

Parents Reply
  • Thank you for your reply.

    I'll test including the at command later.

    I really want edrx example project or tutorial.

    And one more question. For example, if you set 327 sec in edrx interval, does it operate in the interval right after edrx starts? Or the device takes some steps and finally reaches to 327sec like 30, 60, ..., 327? I want to know the specification of nRF9160 eDRX.

Children
No Data
Related