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

How do I disconnect the MQTT correctly?

I tested NB-IoT and MQTT in NRF9160, and the device could normally search for NB signals and connect to our background through MQTT protocol. After the device uploaded data to the background successfully, I wanted to disconnect the MQTT connection, but MQTT returned -128 to me, why?And even then, I can reconnect to MQTT again, but I can't accept the RSRP signal value any more!

my prj.conf file is like this:

#
# Copyright (c) 2019 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
#
# General config
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
CONFIG_ASSERT=y
CONFIG_REBOOT=y
CONFIG_GPIO=y
CONFIG_TRUSTED_EXECUTION_NONSECURE=y

# Log
CONFIG_LOG=y
CONFIG_LOG_IMMEDIATE=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n
CONFIG_LOG_DEFAULT_LEVEL=4
CONFIG_LOG_MODE_OVERFLOW=y
CONFIG_LOG_BACKEND_RTT_MODE_DROP=y
CONFIG_LOG_BACKEND_SHOW_COLOR=n
CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP=n

# Modem info
CONFIG_MODEM_INFO=y

# BSD library
CONFIG_BSD_LIBRARY=y
CONFIG_BSD_LIBRARY_TRACE_ENABLED=n

# Flash
CONFIG_FLASH=y
CONFIG_IMG_ERASE_PROGRESSIVELY=y

# NVS
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_NVS=y
CONFIG_NVS_LOG_LEVEL_DBG=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y

# GPS
CONFIG_AT_CMD=y
CONFIG_AT_NOTIF=y

# AT_CMD
CONFIG_AT_HOST_LIBRARY=y
CONFIG_UART_INTERRUPT_DRIVEN=y

# Console
CONFIG_CONSOLE_SUBSYS=n
CONFIG_CONSOLE_HANDLER=n
CONFIG_CONSOLE_GETCHAR=n
CONFIG_CONSOLE=n
CONFIG_RTT_CONSOLE=n
CONFIG_UART_CONSOLE=n

# Enable SUPL client support AGPS
CONFIG_SUPL_CLIENT_LIB=n

# Network
CONFIG_NETWORKING=y
CONFIG_NET_NATIVE=n
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_SOCKETS_SOCKOPT_TLS=y

# LTE link control
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_AUTO_INIT_AND_CONNECT=n
CONFIG_LTE_NETWORK_USE_FALLBACK=n
CONFIG_LTE_NETWORK_TIMEOUT=60
CONFIG_LTE_NETWORK_MODE_LTE_M_GPS=n
CONFIG_LTE_NETWORK_MODE_NBIOT_GPS=y
CONFIG_LTE_LEGACY_PCO_MODE=y

## PSM
CONFIG_LTE_PSM_ENABLE=y
CONFIG_LTE_PSM_REQ_RPTAU="00100001"
CONFIG_LTE_PSM_REQ_RAT="00000000"

## eDRX
CONFIG_LTE_EDRX_ENABLE=n
CONFIG_LTE_EDRX_REQ_VALUE="1001"

# MQTT
CONFIG_MQTT_LIB=y
CONFIG_MQTT_LIB_TLS=n
CONFIG_MQTT_PUB_TOPIC="device/auri/pushdata"
CONFIG_MQTT_SUB_TOPIC="device/auri/"
CONFIG_MQTT_CLIENT_ID="my-client-id"
CONFIG_MQTT_USER_NAME="admin123"
CONFIG_MQTT_PASSWORD="admin123"
CONFIG_MQTT_BROKER_HOSTNAME="47.107.51.89"
CONFIG_MQTT_BROKER_PORT=1883

# Library for buttons and LEDs
CONFIG_DK_LIBRARY=y
CONFIG_DK_LIBRARY_INVERT_LEDS=n

# Heap and stacks
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_HW_STACK_PROTECTION=y

# MCUBOOT
#CONFIG_BOOTLOADER_MCUBOOT=y
#CONFIG_IMG_MANAGER=y
#CONFIG_MCUBOOT_IMG_MANAGER=y

# SPI
CONFIG_SPI=y
CONFIG_SPI_NRFX=y
CONFIG_SPI_2=y
CONFIG_SPI_2_NRF_SPIM=y
CONFIG_SPI_3=y
CONFIG_SPI_3_NRF_SPIM=y

# I2C
CONFIG_I2C=y
CONFIG_I2C_NRFX=y
CONFIG_I2C_1=y
CONFIG_I2C_1_NRF_TWIM=y
CONFIG_I2C_2=n
CONFIG_I2C_2_NRF_TWIM=n
CONFIG_I2C_INIT_PRIORITY=60

# I2S
CONFIG_NRFX_I2S=y

# UART
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
#CONFIG_UART_LINE_CTRL=y
#CONFIG_UART_0_NRF_UART=y
#CONFIG_UART_0_NRF_UARTE=y
#CONFIG_UART_0_NRF_FLOW_CONTROL=n
#CONFIG_UART_1_NRF_UARTE=n
#CONFIG_UART_1_NRF_FLOW_CONTROL=n

# Device power management
CONFIG_DEVICE_POWER_MANAGEMENT=y

# Use smaller buffers for net_buf as CANBUS packets are quite small.
CONFIG_NET_BUF_DATA_SIZE=64
CONFIG_NET_BUF_USER_DATA_SIZE=1

#CONFIG_SERIAL=n
#CONFIG_LOG=n

/**@brief MQTT client event handler
 */
static void mqtt_evt_handler(struct mqtt_client *const c,
		      const struct mqtt_evt *evt)
{
	int err;

	switch(evt->type)
	{
	case MQTT_EVT_CONNACK:
		if(evt->result != 0)
		{
			LOG_INF("MQTT connect failed %d\n", evt->result);
			break;
		}

		mqtt_connected = true;
		LOG_INF("[%s:%d] MQTT client connected!\n", __func__, __LINE__);
		subscribe();

		NbSendDateStart();
		MqttDicConnectStart();
		//k_delayed_work_submit_to_queue(app_work_q, &mqtt_send_work, K_SECONDS(5));
		break;

	case MQTT_EVT_DISCONNECT:
		LOG_INF("[%s:%d] MQTT client disconnected %d\n", __func__, __LINE__, evt->result);
		mqtt_connected = false;
		
		NbSendDateStop();
		MqttDicConnectStop();
		break;

	case MQTT_EVT_PUBLISH: 
		{
			const struct mqtt_publish_param *p = &evt->param.publish;

			LOG_INF("[%s:%d] MQTT PUBLISH result=%d len=%d\n", __func__, __LINE__, evt->result, p->message.payload.len);
	
			err = publish_get_payload(c, p->message.payload.len);
			if(err >= 0)
			{
				data_print("Received: ", payload_buf,
					p->message.payload.len);
				/* Echo back received data */
				//data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,
				//	payload_buf, p->message.payload.len);
			}
			else
			{
				LOG_INF("mqtt_read_publish_payload: Failed! %d\n", err);
				LOG_INF("Disconnecting MQTT client...\n");
			
				err = mqtt_disconnect(c);
				if(err)
				{
					LOG_INF("Could not disconnect: %d\n", err);
				#ifdef SHOW_LOG_IN_SCREEN	
					sprintf(tmpbuf, "Could not disconnect: %d", err);
					show_infor(tmpbuf);
				#endif
				}
			}
		} 
		break;

	case MQTT_EVT_PUBACK:
		if(evt->result != 0)
		{
			LOG_INF("MQTT PUBACK error %d\n", evt->result);
			break;
		}

		LOG_INF("[%s:%d] PUBACK packet id: %u\n", __func__, __LINE__,
				evt->param.puback.message_id);
		break;

	case MQTT_EVT_SUBACK:
		if(evt->result != 0)
		{
			LOG_INF("MQTT SUBACK error %d\n", evt->result);
			break;
		}

		LOG_INF("[%s:%d] SUBACK packet id: %u\n", __func__, __LINE__,
				evt->param.suback.message_id);
		break;

	default:
		LOG_INF("[%s:%d] default: %d\n", __func__, __LINE__,
				evt->type);
		break;
	}
}

/**@brief Resolves the configured hostname and
 * initializes the MQTT broker structure
 */
static void broker_init(void)
{
	int err;
	struct addrinfo *result;
	struct addrinfo *addr;
	struct addrinfo hints = {
		.ai_family = AF_INET,
		.ai_socktype = SOCK_STREAM
	};

	err = getaddrinfo(CONFIG_MQTT_BROKER_HOSTNAME, NULL, &hints, &result);
	if(err)
	{
		LOG_INF("ERROR: getaddrinfo failed %d\n", err);
		return;
	}

	addr = result;
	err = -ENOENT;

	/* Look for address of the broker. */
	while(addr != NULL)
	{
		/* IPv4 Address. */
		if (addr->ai_addrlen == sizeof(struct sockaddr_in))
		{
			struct sockaddr_in *broker4 =
				((struct sockaddr_in *)&broker);
			char ipv4_addr[NET_IPV4_ADDR_LEN];

			broker4->sin_addr.s_addr =
				((struct sockaddr_in *)addr->ai_addr)
				->sin_addr.s_addr;
			broker4->sin_family = AF_INET;
			broker4->sin_port = htons(CONFIG_MQTT_BROKER_PORT);

			inet_ntop(AF_INET, &broker4->sin_addr.s_addr,
				  ipv4_addr, sizeof(ipv4_addr));
			LOG_INF("IPv4 Address found %s\n", ipv4_addr);
			break;
		}
		else
		{
			LOG_INF("ai_addrlen = %u should be %u or %u\n",
				(unsigned int)addr->ai_addrlen,
				(unsigned int)sizeof(struct sockaddr_in),
				(unsigned int)sizeof(struct sockaddr_in6));
		}

		addr = addr->ai_next;
		break;
	}

	/* Free the address. */
	freeaddrinfo(result);
}

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

	mqtt_client_init(client);

	broker_init();

	/* MQTT client configuration */
	client->broker = &broker;
	
	client->evt_cb = mqtt_evt_handler;
	
	client->client_id.utf8 = (u8_t *)g_imei;	//xb add 2021-03-24 CONFIG_MQTT_CLIENT_ID;
	client->client_id.size = strlen(g_imei);

	password.utf8 = (u8_t *)CONFIG_MQTT_PASSWORD;
	password.size = strlen(CONFIG_MQTT_PASSWORD);
	client->password = &password;

	username.utf8 = (u8_t *)CONFIG_MQTT_USER_NAME;
	username.size = strlen(CONFIG_MQTT_USER_NAME);
	client->user_name = &username;
	
	client->protocol_version = 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);

#if defined(CONFIG_MQTT_LIB_TLS)
    struct mqtt_sec_config *tls_config = &client->transport.tls.config;
    
    client->transport.type = MQTT_TRANSPORT_SECURE;
    
    tls_config->peer_verify = CONFIG_PEER_VERIFY;
    tls_config->cipher_count = 0;
    tls_config->cipher_list = NULL;
    tls_config->sec_tag_count = ARRAY_SIZE(sec_tag_list);
    tls_config->sec_tag_list = sec_tag_list;
    tls_config->hostname = CONFIG_MQTT_BROKER_HOSTNAME;
#else
    client->transport.type = MQTT_TRANSPORT_NON_SECURE;
#endif/* defined(CONFIG_MQTT_LIB_TLS) */
}

/**@brief Initialize the file descriptor structure used by poll.
 */
static int fds_init(struct mqtt_client *c)
{
	if(c->transport.type == MQTT_TRANSPORT_NON_SECURE)
	{
		fds.fd = c->transport.tcp.sock;
	}
	else
	{
	#if defined(CONFIG_MQTT_LIB_TLS)
		fds.fd = c->transport.tls.sock;
	#else
		return -ENOTSUP;
	#endif
	}

	fds.events = POLLIN;

	return 0;
}

static void mqtt_link(struct k_work_q *work_q)
{
	int err,i=0;

	client_init(&client);

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

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

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

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

		if((fds.revents & POLLIN) == POLLIN)
		{
			err = mqtt_input(&client);
			if(err != 0)
			{
				LOG_INF("ERROR: mqtt_input %d\n", err);
				break;
			}
		}

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

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

		//k_sleep(K_MSEC(5000));
	}

	LOG_INF("Disconnecting MQTT client...\n");

	err = mqtt_disconnect(&client);
	if(err)
	{
		LOG_INF("%s: Could not disconnect MQTT client. Error: %d\n", __func__, err);
	}
}
static void MqttDisConnect(void)
{
	int err;

	LOG_INF("%s: begin\n", __func__);
	err = mqtt_disconnect(&client);
	if(err)
	{
		LOG_INF("[%s]: Could not disconnect MQTT client. Error: %d\n", __func__, err);
	}
	
	//err = mqtt_live(&client);
	//if(err != 0)
	//{
	//	LOG_INF("[%s]: ERROR: mqtt_live %d\n", err);
	//}
}

static void MqttDisConnectCallBack(struct k_timer *timer_id)
{
	LOG_INF("%s: begin\n", __func__);
	mqtt_disconnect_flag = true;
}

static void MqttDicConnectStart(void)
{
	LOG_INF("%s: begin\n", __func__);
	k_timer_start(&mqtt_disconnect_timer, K_SECONDS(MQTT_CONNECTED_KEEP_TIME), NULL);
}

Related