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?

