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?