MQTT_Simple Example - Where is the delay?

I've been working on developing an application based on the MQTT_Simple example with TWIM & TWIS added to it.  The application seems to have a 60 second delay before the "while (1)" loop in the "do_connect:" section of the main function and I can't identify where the delay is located in the code.  The delay is skipped and the program goes through the while loop when an MQTT message is received, but if an MQTT message is not received there is the 60 second delay.  I would like to continuously run additional lines of code independent of receiving MQTT messages or this delay.  Any advice would be greatly appreciated.  My code is as follows:

#include <zephyr/kernel.h>
#include <stdio.h>
#include <stdint.h>
#include <zephyr/drivers/uart.h>
#include <string.h>
#include <zephyr/random/rand32.h>
#include <zephyr/net/mqtt.h>
#include <zephyr/net/socket.h>
#include <zephyr/shell/shell.h>
#include <hw_id.h>
#if defined(CONFIG_NRF_MODEM_LIB)
#include <nrf_modem_at.h>
#endif /* CONFIG_NRF_MODEM_LIB */
#include <modem/lte_lc.h>
#include <zephyr/logging/log.h>
#if defined(CONFIG_MODEM_KEY_MGMT)
#include <modem/modem_key_mgmt.h>
#endif
#include <dk_buttons_and_leds.h>

#include "certificates.h"


#include <nrfx_twim.h>
#include <nrfx_twis.h>

/**
 * @defgroup nrfx_twim_twis_non_blocking_example Non-blocking TWIM with TWIS example
 * @{
 * @ingroup nrfx_twim_twis_examples
 *
 * @brief Example showing the functionality of nrfx_twim and nrfx_twis drivers operating in the
 *        non-blocking mode.
 *
 * @details Application initializes nrfx_twim and nrfx_twis drivers, then sends the specified message
 *          ( @ref MSG_TO_SEND ) from master to slave and back using TWIM and TWIS peripherals.
 *          To perform this operation different buffers are used and data is transferred as follows:
 *          @ref m_tx_buffer_master -> @ref m_rx_buffer_slave -> @ref m_rx_buffer_master
 *          The @ref twim_handler() and @ref twis_handler() are executed with relevant log messages.
 */

#define LOOPBACK_PIN_1A 3
#define LOOPBACK_PIN_1B 31
#define LOOPBACK_PIN_2A 4
#define LOOPBACK_PIN_2B 30

/** @brief Symbol specifying pin number of master SCL. */
#define MASTER_SCL_PIN LOOPBACK_PIN_1A

/** @brief Symbol specifying pin number of master SDA. */
#define MASTER_SDA_PIN LOOPBACK_PIN_2A

/** @brief Symbol specifying pin number of slave SCL. */
#define SLAVE_SCL_PIN LOOPBACK_PIN_1B

/** @brief Symbol specifying pin number of slave SDA. */
#define SLAVE_SDA_PIN LOOPBACK_PIN_2B

#define TWIM_INST_IDX 1
#define TWIS_INST_IDX 2

/** @brief Symbol specifying slave address on TWI bus. */
#define SLAVE_ADDR 0x0B

/** @brief Symbol specifying message to be sent via TWIM data transfer.*/
#define MSG_TO_SEND "Nordic Semiconductor"

/** @brief Structure containing TWIS driver instance. */
static nrfx_twis_t twis_inst = NRFX_TWIS_INSTANCE(TWIS_INST_IDX);

/** @brief Structure containing TWIM driver instance. */
static nrfx_twim_t twim_inst = NRFX_TWIM_INSTANCE(TWIM_INST_IDX);

/** @brief TWIM transmit buffer initialized with @ref MSG_TO_SEND. */
static uint8_t m_tx_buffer_master[] = MSG_TO_SEND;

/** @brief TWIS recieve buffer for a message from TWIM. */
static uint8_t m_rx_buffer_slave[sizeof(MSG_TO_SEND)];

/** @brief TWIM recieve buffer for a message from TWIS. */
static uint8_t m_rx_buffer_master[sizeof(MSG_TO_SEND)];



LOG_MODULE_REGISTER(mqtt_simple, CONFIG_MQTT_SIMPLE_LOG_LEVEL);

/* Buffers for MQTT client. */
static uint8_t rx_buffer[CONFIG_MQTT_MESSAGE_BUFFER_SIZE];
static uint8_t tx_buffer[CONFIG_MQTT_MESSAGE_BUFFER_SIZE];
static uint8_t payload_buf[CONFIG_MQTT_PAYLOAD_BUFFER_SIZE];

/* The mqtt client struct */
static struct mqtt_client client;

/* MQTT Broker details. */
static struct sockaddr_storage broker;

/* File descriptor */
static struct pollfd fds;

#if defined(CONFIG_MQTT_LIB_TLS)
static int certificates_provision(void)
{
	int err = 0;

	LOG_INF("Provisioning certificates");

#if defined(CONFIG_NRF_MODEM_LIB) && defined(CONFIG_MODEM_KEY_MGMT)

	err = modem_key_mgmt_write(CONFIG_MQTT_TLS_SEC_TAG,
				   MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN,
				   CA_CERTIFICATE,
				   strlen(CA_CERTIFICATE));
	if (err) {
		LOG_ERR("Failed to provision CA certificate: %d", err);
		return err;
	}

#elif defined(CONFIG_BOARD_QEMU_X86) && defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)

	err = tls_credential_add(CONFIG_MQTT_TLS_SEC_TAG,
				 TLS_CREDENTIAL_CA_CERTIFICATE,
				 CA_CERTIFICATE,
				 sizeof(CA_CERTIFICATE));
	if (err) {
		LOG_ERR("Failed to register CA certificate: %d", err);
		return err;
	}

#endif

	return err;
}
#endif /* defined(CONFIG_MQTT_LIB_TLS) */

/**@brief Function to print strings without null-termination
 */
static void data_print(uint8_t *prefix, uint8_t *data, size_t len)
{
	char buf[len + 1];

	memcpy(buf, data, len);
	buf[len] = 0;
	LOG_INF("%s%s", (char *)prefix, (char *)buf);
}

/**@brief Function to publish data on the configured topic
 */
static int data_publish(struct mqtt_client *c, enum mqtt_qos qos,
	uint8_t *data, size_t len)
{
	struct mqtt_publish_param param;

	param.message.topic.qos = qos;
	param.message.topic.topic.utf8 = CONFIG_MQTT_PUB_TOPIC;
	param.message.topic.topic.size = strlen(CONFIG_MQTT_PUB_TOPIC);
	param.message.payload.data = data;
	param.message.payload.len = len;
	param.message_id = sys_rand32_get();
	param.dup_flag = 0;
	param.retain_flag = 0;

	data_print("Publishing: ", data, len);
	LOG_INF("to topic: %s len: %u",
		CONFIG_MQTT_PUB_TOPIC,
		(unsigned int)strlen(CONFIG_MQTT_PUB_TOPIC));

	return mqtt_publish(c, &param);
}

/**@brief Function to subscribe to the configured topic
 */
static int subscribe(void)
{
	struct mqtt_topic subscribe_topic = {
		.topic = {
			.utf8 = CONFIG_MQTT_SUB_TOPIC,
			.size = strlen(CONFIG_MQTT_SUB_TOPIC)
		},
		.qos = MQTT_QOS_1_AT_LEAST_ONCE
	};

	const struct mqtt_subscription_list subscription_list = {
		.list = &subscribe_topic,
		.list_count = 1,
		.message_id = 1234
	};

	LOG_INF("Subscribing to: %s len %u", CONFIG_MQTT_SUB_TOPIC,
		(unsigned int)strlen(CONFIG_MQTT_SUB_TOPIC));

	return mqtt_subscribe(&client, &subscription_list);
}

/**@brief Function to read the published payload.
 */
static int publish_get_payload(struct mqtt_client *c, size_t length)
{
	int ret;
	int err = 0;

	/* Return an error if the payload is larger than the payload buffer.
	 * Note: To allow new messages, we have to read the payload before returning.
	 */
	if (length > sizeof(payload_buf)) {
		err = -EMSGSIZE;
	}

	/* Truncate payload until it fits in the payload buffer. */
	while (length > sizeof(payload_buf)) {
		ret = mqtt_read_publish_payload_blocking(
				c, payload_buf, (length - sizeof(payload_buf)));
		if (ret == 0) {
			return -EIO;
		} else if (ret < 0) {
			return ret;
		}

		length -= ret;
	}

	ret = mqtt_readall_publish_payload(c, payload_buf, length);
	if (ret) {
		return ret;
	}

	return err;
}

/**@brief MQTT client event handler
 */
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_ERR("MQTT connect failed: %d", evt->result);
			break;
		}

		LOG_INF("MQTT client connected");
		subscribe();
		break;

	case MQTT_EVT_DISCONNECT:
		LOG_INF("MQTT client disconnected: %d", evt->result);
		break;

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

		LOG_INF("MQTT PUBLISH result=%d len=%d",
			evt->result, p->message.payload.len);
		err = publish_get_payload(c, p->message.payload.len);

		if (p->message.topic.qos == MQTT_QOS_1_AT_LEAST_ONCE) {
			const struct mqtt_puback_param ack = {
				.message_id = p->message_id
			};

			/* Send acknowledgment. */
			mqtt_publish_qos1_ack(&client, &ack);
		}

		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 if (err == -EMSGSIZE) {
			LOG_ERR("Received payload (%d bytes) is larger than the payload buffer "
				"size (%d bytes).",
				p->message.payload.len, sizeof(payload_buf));
		} else {
			LOG_ERR("publish_get_payload failed: %d", err);
			LOG_INF("Disconnecting MQTT client...");

			err = mqtt_disconnect(c);
			if (err) {
				LOG_ERR("Could not disconnect: %d", err);
			}
		}
	} break;

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

		LOG_INF("PUBACK packet id: %u", evt->param.puback.message_id);
		break;

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

		LOG_INF("SUBACK packet id: %u", evt->param.suback.message_id);
		break;

	case MQTT_EVT_PINGRESP:
		if (evt->result != 0) {
			LOG_ERR("MQTT PINGRESP error: %d", evt->result);
		}
		break;

	default:
		LOG_INF("Unhandled MQTT event type: %d", evt->type);
		break;
	}
}

/**@brief Resolves the configured hostname and
 * initializes the MQTT broker structure
 */
static int 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_ERR("getaddrinfo failed: %d", err);
		return -ECHILD;
	}

	addr = result;

	/* 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", ipv4_addr);

			break;
		} else {
			LOG_ERR("ai_addrlen = %u should be %u or %u",
				(unsigned int)addr->ai_addrlen,
				(unsigned int)sizeof(struct sockaddr_in),
				(unsigned int)sizeof(struct sockaddr_in6));
		}

		addr = addr->ai_next;
	}

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

	return err;
}

#define RANDOM_LEN 10
#define CLIENT_ID_LEN sizeof(CONFIG_BOARD) + 1 + RANDOM_LEN

/* Function to get the client id */
static const uint8_t* client_id_get(void)
{
	static uint8_t client_id[MAX(sizeof(CONFIG_MQTT_CLIENT_ID),
				     CLIENT_ID_LEN)];

	if (strlen(CONFIG_MQTT_CLIENT_ID) > 0) {
		snprintf(client_id, sizeof(client_id), "%s",
			 CONFIG_MQTT_CLIENT_ID);
		goto exit;
	}

	char hw_id_buf[HW_ID_LEN] = {0};

	int err = hw_id_get(hw_id_buf, ARRAY_SIZE(hw_id_buf));

	if (!err) {
		snprintf(client_id, sizeof(client_id), "nrf-%s",
			 hw_id_buf);
		goto exit;
	}

	LOG_ERR("failed to retrieve HW ID, err: %d", err);

	uint32_t id = sys_rand32_get();
	snprintf(client_id, sizeof(client_id), "%s-%010u", CONFIG_BOARD, id);

exit:
	LOG_DBG("client_id = %s", (char *)client_id);

	return client_id;
}

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

	mqtt_client_init(client);

	err = broker_init();
	if (err) {
		LOG_ERR("Failed to initialize broker connection");
		return err;
	}

	/* MQTT client configuration */
	client->broker = &broker;
	client->evt_cb = mqtt_evt_handler;
	client->client_id.utf8 = client_id_get();
	client->client_id.size = strlen(client->client_id.utf8);
	struct mqtt_utf8 pass,name;
    pass.size = (uint32_t)strlen("****************");
    pass.utf8 =(uint8_t*)"****************";
    printk("pass: %d,%s\n",pass.size,pass.utf8);
    name.size = (uint32_t) strlen("****************");
    name.utf8 = (uint8_t*)"****************";
    printk("name: %d,%s\n",name.size,name.utf8);

    client->password = &pass;
    client->user_name = &name;
	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);

	/* MQTT transport configuration */
#if defined(CONFIG_MQTT_LIB_TLS)
	struct mqtt_sec_config *tls_cfg = &(client->transport).tls.config;
	static sec_tag_t sec_tag_list[] = { CONFIG_MQTT_TLS_SEC_TAG };

	LOG_INF("TLS enabled");
	client->transport.type = MQTT_TRANSPORT_SECURE;

	tls_cfg->peer_verify = CONFIG_MQTT_TLS_PEER_VERIFY;
	tls_cfg->cipher_count = 0;
	tls_cfg->cipher_list = NULL;
	tls_cfg->sec_tag_count = ARRAY_SIZE(sec_tag_list);
	tls_cfg->sec_tag_list = sec_tag_list;
	tls_cfg->hostname = CONFIG_MQTT_BROKER_HOSTNAME;

#if defined(CONFIG_NRF_MODEM_LIB)
	tls_cfg->session_cache = IS_ENABLED(CONFIG_MQTT_TLS_SESSION_CACHING) ?
					    TLS_SESSION_CACHE_ENABLED :
					    TLS_SESSION_CACHE_DISABLED;
#else
	/* TLS session caching is not supported by the Zephyr network stack */
	tls_cfg->session_cache = TLS_SESSION_CACHE_DISABLED;

#endif

#else
	client->transport.type = MQTT_TRANSPORT_NON_SECURE;
#endif

	return err;
}

/**@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;
}

#if defined(CONFIG_DK_LIBRARY)
static void button_handler(uint32_t button_states, uint32_t has_changed)
{
	if (has_changed & button_states &
	    BIT(CONFIG_BUTTON_EVENT_BTN_NUM - 1)) {
		int ret;

		ret = data_publish(&client,
				   MQTT_QOS_1_AT_LEAST_ONCE,
				   CONFIG_BUTTON_EVENT_PUBLISH_MSG,
				   sizeof(CONFIG_BUTTON_EVENT_PUBLISH_MSG)-1);
		if (ret) {
			LOG_ERR("Publish failed: %d", ret);
		}
	}
}
#endif

static int shell_mqtt_publish(const struct shell *shell, size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	int ret;

	ret = data_publish(&client,
			   MQTT_QOS_1_AT_LEAST_ONCE,
			   CONFIG_BUTTON_EVENT_PUBLISH_MSG,
			   sizeof(CONFIG_BUTTON_EVENT_PUBLISH_MSG) - 1);
	if (ret) {
		LOG_ERR("Publish failed: %d", ret);
	}

	return ret;
}

SHELL_STATIC_SUBCMD_SET_CREATE(mqtt_sub,
		SHELL_CMD(publish, NULL, "Publish data to configured publish topic",
			shell_mqtt_publish),
		SHELL_SUBCMD_SET_END /* Array terminated. */
);
SHELL_CMD_REGISTER(mqtt, &mqtt_sub, "MQTT operations", NULL);

/**@brief Configures modem to provide LTE link. Blocks until link is
 * successfully established.
 */
static int modem_configure(void)
{
#if defined(CONFIG_LTE_LINK_CONTROL)
	/* Turn off LTE power saving features for a more responsive demo. Also,
	 * request power saving features before network registration. Some
	 * networks rejects timer updates after the device has registered to the
	 * LTE network.
	 */
	LOG_INF("Disabling PSM and eDRX");
	lte_lc_psm_req(false);
	lte_lc_edrx_req(false);

	if (IS_ENABLED(CONFIG_LTE_AUTO_INIT_AND_CONNECT)) {
		/* Do nothing, modem is already turned on
		 * and connected.
		 */
	} else {
		int err;

		LOG_INF("LTE Link Connecting...");
		err = lte_lc_init_and_connect();
		if (err) {
			LOG_INF("Failed to establish LTE connection: %d", err);
			return err;
		}
		LOG_INF("LTE Link Connected!");
	}
#endif /* defined(CONFIG_LTE_LINK_CONTROL) */

	return 0;
}



/**
 * @brief Function for handling TWIM driver events.
 *
 * @param[in] p_event   Event information structure.
 * @param[in] p_context General purpose parameter set during initialization of the TWIM.
 *                      This parameter can be used to pass additional information to the
 *                      handler function. In this example @p p_context is used to pass address
 *                      of TWI transfer descriptor structure.
 */
static void twim_handler(nrfx_twim_evt_t const * p_event, void * p_context)
{
    nrfx_err_t status;
    (void)status;

    nrfx_twim_xfer_desc_t * twim_desc = p_context;
    static bool m_master_done = false;

    if (p_event->type == NRFX_TWIM_EVT_DONE)
    {
        LOG_INF("--> Master event: done - transfer completed");
        twim_desc->type = NRFX_TWIM_XFER_RX;
        twim_desc->p_primary_buf = m_rx_buffer_master;

        if (!m_master_done)
        {
            status = nrfx_twim_xfer(&twim_inst, twim_desc, 0);
            NRFX_ASSERT(status == NRFX_SUCCESS);
            m_master_done = true;
        }
        else
        {
            LOG_INF("Content of master RX buffer: %s", m_rx_buffer_master);
        }
    }
    else
    {
        LOG_INF("--> MASTER handler, event: %d.", p_event->type);
    }
}

/**
 * @brief Function for handling TWIS driver events.
 *
 * @param[in] p_event Event information structure.
 */
static void twis_handler(nrfx_twis_evt_t const * p_event)
{
    nrfx_err_t status;
    (void)status;

    switch (p_event->type)
    {
        case NRFX_TWIS_EVT_WRITE_DONE:
            LOG_INF("--> Slave event: write done.");
            break;

        case NRFX_TWIS_EVT_READ_DONE:
            LOG_INF("--> Slave event: read done.");
            break;

        case NRFX_TWIS_EVT_WRITE_REQ:
            status = nrfx_twis_rx_prepare(&twis_inst, m_rx_buffer_slave, sizeof(m_rx_buffer_slave));
            NRFX_ASSERT(status == NRFX_SUCCESS);
            LOG_INF("--> Slave event: write request");
            break;

        case NRFX_TWIS_EVT_READ_REQ:
            status = nrfx_twis_tx_prepare(&twis_inst, m_rx_buffer_slave, sizeof(m_rx_buffer_slave));
            NRFX_ASSERT(status == NRFX_SUCCESS);
            LOG_INF("--> Slave event: read request");
            break;

        default:
            LOG_INF("--> SLAVE event: %d.", p_event->type);
    }
}



void main(void)
{
	int err;
	uint32_t connect_attempt = 0;

	LOG_INF("The MQTT simple sample started");





	nrfx_err_t status;
	(void)status;
	LOG_INF("Starting nrfx_twim_twis non-blocking example.");
	nrfx_twim_xfer_desc_t twim_xfer_desc = NRFX_TWIM_XFER_DESC_TX(SLAVE_ADDR,
                                                                  m_tx_buffer_master,
                                                                  sizeof(m_tx_buffer_master));
	nrfx_twim_config_t twim_config = NRFX_TWIM_DEFAULT_CONFIG(MASTER_SCL_PIN, MASTER_SDA_PIN);
    status = nrfx_twim_init(&twim_inst, &twim_config, twim_handler, &twim_xfer_desc);
	nrfx_twis_config_t twis_config = NRFX_TWIS_DEFAULT_CONFIG(SLAVE_SCL_PIN,
                                                              SLAVE_SDA_PIN,
                                                              SLAVE_ADDR);
	status = nrfx_twis_init(&twis_inst, &twis_config, twis_handler);
	
	#if defined(__ZEPHYR__)
        #define TWIM_INST         NRFX_CONCAT_2(NRF_TWIM, TWIM_INST_IDX)
        #define TWIM_INST_HANDLER NRFX_CONCAT_3(nrfx_twim_, TWIM_INST_IDX, _irq_handler)
        IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(TWIM_INST), IRQ_PRIO_LOWEST, TWIM_INST_HANDLER, 0);

        #define TWIS_INST         NRFX_CONCAT_2(NRF_TWIS, TWIS_INST_IDX)
        #define TWIS_INST_HANDLER NRFX_CONCAT_3(nrfx_twis_, TWIS_INST_IDX, _irq_handler)
        IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(TWIS_INST), IRQ_PRIO_LOWEST, TWIS_INST_HANDLER, 0);
    #endif

	nrfx_twim_enable(&twim_inst);
	nrfx_twis_enable(&twis_inst);
	status = nrfx_twim_xfer(&twim_inst, &twim_xfer_desc, 0);


#if defined(CONFIG_MQTT_LIB_TLS)
	err = certificates_provision();
	if (err != 0) {
		LOG_ERR("Failed to provision certificates");
		return;
	}
#endif /* defined(CONFIG_MQTT_LIB_TLS) */
      
	do {
		err = modem_configure();
		if (err) {
			LOG_INF("Retrying in %d seconds",
				CONFIG_LTE_CONNECT_RETRY_DELAY_S);
			k_sleep(K_SECONDS(CONFIG_LTE_CONNECT_RETRY_DELAY_S));
		}
	} while (err);

	err = client_init(&client);
	if (err != 0) {
		LOG_ERR("client_init: %d", err);
		return;
	}

#if defined(CONFIG_DK_LIBRARY)
	dk_buttons_init(button_handler);
#endif




do_connect:
	if (connect_attempt++ > 0) {
		LOG_INF("Reconnecting in %d seconds...",
			CONFIG_MQTT_RECONNECT_DELAY_S);
		k_sleep(K_SECONDS(CONFIG_MQTT_RECONNECT_DELAY_S));
	}
	err = mqtt_connect(&client);
	if (err != 0) {
		LOG_ERR("mqtt_connect %d", err);
		goto do_connect;
	}

	err = fds_init(&client);
	if (err != 0) {
		LOG_ERR("fds_init: %d", err);
		return;
	}

	while (1) {
		LOG_INF("Messagetest");
		LOG_INF("Message to send: %s", m_tx_buffer_master);
		LOG_INF("Content of master RX buffer: %s", m_rx_buffer_master);

		err = poll(&fds, 1, mqtt_keepalive_time_left(&client));
		if (err < 0) {
			LOG_ERR("poll: %d", errno);
			break;
		}

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

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

		if ((fds.revents & POLLERR) == POLLERR) {
			LOG_ERR("POLLERR");
			break;
		}

		if ((fds.revents & POLLNVAL) == POLLNVAL) {
			LOG_ERR("POLLNVAL");
			break;
		}
	}

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

	err = mqtt_disconnect(&client);
	if (err) {
		LOG_ERR("Could not disconnect MQTT client: %d", err);
	}
	goto do_connect;
}






Parents Reply
  • Thanks Charlie.  I think this is actually governed by the "MQTT_KEEPALIVE" value in Kconfig.  As shown in the picture, the TWIM/TWIS strings are logged in the terminal only when this reconnect delay timer has triggered.  I would like to have these strings logged continuously at a different time frequency.  Do you have any suggestions on how to accomplish this with the code as shown?

Children
  • Hello,

    The first line in the while(1)-loop is a polling function. Lets have a look at it:

       err = poll(&fds, 1, mqtt_keepalive_time_left(&client));
    So, if the fds get a flag (mqtt rx), it will loop through the code. If not, it will continue polling for mqtt_keepalive_time_left(&client). This will be the keepalive-value.
    What you could do, is to use this as a "mqtt handle thread", which keeps the connection alive and does something with any data it receives. Then you could use a different thread to do any sending in any frequency you'd like.
    I hope this helps!
    Kind regards,
    Torje
  • Thanks Torje.  I created a thread for handling the MQTT stuff and it seems to work perfectly.  Here is my code and a screenshot of what I'm seeing in case anyone finds use of it.

    #include <zephyr/kernel.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <zephyr/drivers/uart.h>
    #include <string.h>
    #include <zephyr/random/rand32.h>
    #include <zephyr/net/mqtt.h>
    #include <zephyr/net/socket.h>
    #include <zephyr/shell/shell.h>
    #include <hw_id.h>
    #if defined(CONFIG_NRF_MODEM_LIB)
    #include <nrf_modem_at.h>
    #endif /* CONFIG_NRF_MODEM_LIB */
    #include <modem/lte_lc.h>
    #include <zephyr/logging/log.h>
    #if defined(CONFIG_MODEM_KEY_MGMT)
    #include <modem/modem_key_mgmt.h>
    #endif
    #include <dk_buttons_and_leds.h>
    
    #include "certificates.h"
    
    
    #include <nrfx_twim.h>
    #include <nrfx_twis.h>
    
    #include <pthread.h>
    
    /**
     * @defgroup nrfx_twim_twis_non_blocking_example Non-blocking TWIM with TWIS example
     * @{
     * @ingroup nrfx_twim_twis_examples
     *
     * @brief Example showing the functionality of nrfx_twim and nrfx_twis drivers operating in the
     *        non-blocking mode.
     *
     * @details Application initializes nrfx_twim and nrfx_twis drivers, then sends the specified message
     *          ( @ref MSG_TO_SEND ) from master to slave and back using TWIM and TWIS peripherals.
     *          To perform this operation different buffers are used and data is transferred as follows:
     *          @ref m_tx_buffer_master -> @ref m_rx_buffer_slave -> @ref m_rx_buffer_master
     *          The @ref twim_handler() and @ref twis_handler() are executed with relevant log messages.
     */
    
    #define LOOPBACK_PIN_1A 3
    #define LOOPBACK_PIN_1B 31
    #define LOOPBACK_PIN_2A 4
    #define LOOPBACK_PIN_2B 30
    
    /** @brief Symbol specifying pin number of master SCL. */
    #define MASTER_SCL_PIN LOOPBACK_PIN_1A
    
    /** @brief Symbol specifying pin number of master SDA. */
    #define MASTER_SDA_PIN LOOPBACK_PIN_2A
    
    /** @brief Symbol specifying pin number of slave SCL. */
    #define SLAVE_SCL_PIN LOOPBACK_PIN_1B
    
    /** @brief Symbol specifying pin number of slave SDA. */
    #define SLAVE_SDA_PIN LOOPBACK_PIN_2B
    
    #define TWIM_INST_IDX 1
    #define TWIS_INST_IDX 2
    
    /** @brief Symbol specifying slave address on TWI bus. */
    #define SLAVE_ADDR 0x0B
    
    /** @brief Symbol specifying message to be sent via TWIM data transfer.*/
    #define MSG_TO_SEND "Nordic Semiconductor"
    
    /** @brief Structure containing TWIS driver instance. */
    static nrfx_twis_t twis_inst = NRFX_TWIS_INSTANCE(TWIS_INST_IDX);
    
    /** @brief Structure containing TWIM driver instance. */
    static nrfx_twim_t twim_inst = NRFX_TWIM_INSTANCE(TWIM_INST_IDX);
    
    /** @brief TWIM transmit buffer initialized with @ref MSG_TO_SEND. */
    static uint8_t m_tx_buffer_master[] = MSG_TO_SEND;
    
    /** @brief TWIS recieve buffer for a message from TWIM. */
    static uint8_t m_rx_buffer_slave[sizeof(MSG_TO_SEND)];
    
    /** @brief TWIM recieve buffer for a message from TWIS. */
    static uint8_t m_rx_buffer_master[sizeof(MSG_TO_SEND)];
    
    
    
    LOG_MODULE_REGISTER(mqtt_simple, CONFIG_MQTT_SIMPLE_LOG_LEVEL);
    
    /* Buffers for MQTT client. */
    static uint8_t rx_buffer[CONFIG_MQTT_MESSAGE_BUFFER_SIZE];
    static uint8_t tx_buffer[CONFIG_MQTT_MESSAGE_BUFFER_SIZE];
    static uint8_t payload_buf[CONFIG_MQTT_PAYLOAD_BUFFER_SIZE];
    
    /* The mqtt client struct */
    static struct mqtt_client client;
    
    /* MQTT Broker details. */
    static struct sockaddr_storage broker;
    
    /* File descriptor */
    static struct pollfd fds;
    
    #if defined(CONFIG_MQTT_LIB_TLS)
    static int certificates_provision(void)
    {
    	int err = 0;
    
    	LOG_INF("Provisioning certificates");
    
    #if defined(CONFIG_NRF_MODEM_LIB) && defined(CONFIG_MODEM_KEY_MGMT)
    
    	err = modem_key_mgmt_write(CONFIG_MQTT_TLS_SEC_TAG,
    				   MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN,
    				   CA_CERTIFICATE,
    				   strlen(CA_CERTIFICATE));
    	if (err) {
    		LOG_ERR("Failed to provision CA certificate: %d", err);
    		return err;
    	}
    
    #elif defined(CONFIG_BOARD_QEMU_X86) && defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
    
    	err = tls_credential_add(CONFIG_MQTT_TLS_SEC_TAG,
    				 TLS_CREDENTIAL_CA_CERTIFICATE,
    				 CA_CERTIFICATE,
    				 sizeof(CA_CERTIFICATE));
    	if (err) {
    		LOG_ERR("Failed to register CA certificate: %d", err);
    		return err;
    	}
    
    #endif
    
    	return err;
    }
    #endif /* defined(CONFIG_MQTT_LIB_TLS) */
    
    /**@brief Function to print strings without null-termination
     */
    static void data_print(uint8_t *prefix, uint8_t *data, size_t len)
    {
    	char buf[len + 1];
    
    	memcpy(buf, data, len);
    	buf[len] = 0;
    	LOG_INF("%s%s", (char *)prefix, (char *)buf);
    }
    
    /**@brief Function to publish data on the configured topic
     */
    static int data_publish(struct mqtt_client *c, enum mqtt_qos qos,
    	uint8_t *data, size_t len)
    {
    	struct mqtt_publish_param param;
    
    	param.message.topic.qos = qos;
    	param.message.topic.topic.utf8 = CONFIG_MQTT_PUB_TOPIC;
    	param.message.topic.topic.size = strlen(CONFIG_MQTT_PUB_TOPIC);
    	param.message.payload.data = data;
    	param.message.payload.len = len;
    	param.message_id = sys_rand32_get();
    	param.dup_flag = 0;
    	param.retain_flag = 0;
    
    	data_print("Publishing: ", data, len);
    	LOG_INF("to topic: %s len: %u",
    		CONFIG_MQTT_PUB_TOPIC,
    		(unsigned int)strlen(CONFIG_MQTT_PUB_TOPIC));
    
    	return mqtt_publish(c, &param);
    }
    
    /**@brief Function to subscribe to the configured topic
     */
    static int subscribe(void)
    {
    	struct mqtt_topic subscribe_topic = {
    		.topic = {
    			.utf8 = CONFIG_MQTT_SUB_TOPIC,
    			.size = strlen(CONFIG_MQTT_SUB_TOPIC)
    		},
    		.qos = MQTT_QOS_1_AT_LEAST_ONCE
    	};
    
    	const struct mqtt_subscription_list subscription_list = {
    		.list = &subscribe_topic,
    		.list_count = 1,
    		.message_id = 1234
    	};
    
    	LOG_INF("Subscribing to: %s len %u", CONFIG_MQTT_SUB_TOPIC,
    		(unsigned int)strlen(CONFIG_MQTT_SUB_TOPIC));
    
    	return mqtt_subscribe(&client, &subscription_list);
    }
    
    /**@brief Function to read the published payload.
     */
    static int publish_get_payload(struct mqtt_client *c, size_t length)
    {
    	int ret;
    	int err = 0;
    
    	/* Return an error if the payload is larger than the payload buffer.
    	 * Note: To allow new messages, we have to read the payload before returning.
    	 */
    	if (length > sizeof(payload_buf)) {
    		err = -EMSGSIZE;
    	}
    
    	/* Truncate payload until it fits in the payload buffer. */
    	while (length > sizeof(payload_buf)) {
    		ret = mqtt_read_publish_payload_blocking(
    				c, payload_buf, (length - sizeof(payload_buf)));
    		if (ret == 0) {
    			return -EIO;
    		} else if (ret < 0) {
    			return ret;
    		}
    
    		length -= ret;
    	}
    
    	ret = mqtt_readall_publish_payload(c, payload_buf, length);
    	if (ret) {
    		return ret;
    	}
    
    	return err;
    }
    
    /**@brief MQTT client event handler
     */
    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_ERR("MQTT connect failed: %d", evt->result);
    			break;
    		}
    
    		LOG_INF("MQTT client connected");
    		subscribe();
    		break;
    
    	case MQTT_EVT_DISCONNECT:
    		LOG_INF("MQTT client disconnected: %d", evt->result);
    		break;
    
    	case MQTT_EVT_PUBLISH: {
    		const struct mqtt_publish_param *p = &evt->param.publish;
    
    		LOG_INF("MQTT PUBLISH result=%d len=%d",
    			evt->result, p->message.payload.len);
    		err = publish_get_payload(c, p->message.payload.len);
    
    		if (p->message.topic.qos == MQTT_QOS_1_AT_LEAST_ONCE) {
    			const struct mqtt_puback_param ack = {
    				.message_id = p->message_id
    			};
    
    			/* Send acknowledgment. */
    			mqtt_publish_qos1_ack(&client, &ack);
    		}
    
    		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 if (err == -EMSGSIZE) {
    			LOG_ERR("Received payload (%d bytes) is larger than the payload buffer "
    				"size (%d bytes).",
    				p->message.payload.len, sizeof(payload_buf));
    		} else {
    			LOG_ERR("publish_get_payload failed: %d", err);
    			LOG_INF("Disconnecting MQTT client...");
    
    			err = mqtt_disconnect(c);
    			if (err) {
    				LOG_ERR("Could not disconnect: %d", err);
    			}
    		}
    	} break;
    
    	case MQTT_EVT_PUBACK:
    		if (evt->result != 0) {
    			LOG_ERR("MQTT PUBACK error: %d", evt->result);
    			break;
    		}
    
    		LOG_INF("PUBACK packet id: %u", evt->param.puback.message_id);
    		break;
    
    	case MQTT_EVT_SUBACK:
    		if (evt->result != 0) {
    			LOG_ERR("MQTT SUBACK error: %d", evt->result);
    			break;
    		}
    
    		LOG_INF("SUBACK packet id: %u", evt->param.suback.message_id);
    		break;
    
    	case MQTT_EVT_PINGRESP:
    		if (evt->result != 0) {
    			LOG_ERR("MQTT PINGRESP error: %d", evt->result);
    		}
    		break;
    
    	default:
    		LOG_INF("Unhandled MQTT event type: %d", evt->type);
    		break;
    	}
    }
    
    /**@brief Resolves the configured hostname and
     * initializes the MQTT broker structure
     */
    static int 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_ERR("getaddrinfo failed: %d", err);
    		return -ECHILD;
    	}
    
    	addr = result;
    
    	/* 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", ipv4_addr);
    
    			break;
    		} else {
    			LOG_ERR("ai_addrlen = %u should be %u or %u",
    				(unsigned int)addr->ai_addrlen,
    				(unsigned int)sizeof(struct sockaddr_in),
    				(unsigned int)sizeof(struct sockaddr_in6));
    		}
    
    		addr = addr->ai_next;
    	}
    
    	/* Free the address. */
    	freeaddrinfo(result);
    
    	return err;
    }
    
    #define RANDOM_LEN 10
    #define CLIENT_ID_LEN sizeof(CONFIG_BOARD) + 1 + RANDOM_LEN
    
    /* Function to get the client id */
    static const uint8_t* client_id_get(void)
    {
    	static uint8_t client_id[MAX(sizeof(CONFIG_MQTT_CLIENT_ID),
    				     CLIENT_ID_LEN)];
    
    	if (strlen(CONFIG_MQTT_CLIENT_ID) > 0) {
    		snprintf(client_id, sizeof(client_id), "%s",
    			 CONFIG_MQTT_CLIENT_ID);
    		goto exit;
    	}
    
    	char hw_id_buf[HW_ID_LEN] = {0};
    
    	int err = hw_id_get(hw_id_buf, ARRAY_SIZE(hw_id_buf));
    
    	if (!err) {
    		snprintf(client_id, sizeof(client_id), "nrf-%s",
    			 hw_id_buf);
    		goto exit;
    	}
    
    	LOG_ERR("failed to retrieve HW ID, err: %d", err);
    
    	uint32_t id = sys_rand32_get();
    	snprintf(client_id, sizeof(client_id), "%s-%010u", CONFIG_BOARD, id);
    
    exit:
    	LOG_DBG("client_id = %s", (char *)client_id);
    
    	return client_id;
    }
    
    /**@brief Initialize the MQTT client structure
     */
    static int client_init(struct mqtt_client *client)
    {
    	int err;
    
    	mqtt_client_init(client);
    
    	err = broker_init();
    	if (err) {
    		LOG_ERR("Failed to initialize broker connection");
    		return err;
    	}
    
    	/* MQTT client configuration */
    	client->broker = &broker;
    	client->evt_cb = mqtt_evt_handler;
    	client->client_id.utf8 = client_id_get();
    	client->client_id.size = strlen(client->client_id.utf8);
    	struct mqtt_utf8 pass,name;
        pass.size = (uint32_t)strlen("");
        pass.utf8 =(uint8_t*)"";
        printk("pass: %d,%s\n",pass.size,pass.utf8);
        name.size = (uint32_t) strlen("");
        name.utf8 = (uint8_t*)"";
        printk("name: %d,%s\n",name.size,name.utf8);
    
        client->password = &pass;
        client->user_name = &name;
    	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);
    
    	/* MQTT transport configuration */
    #if defined(CONFIG_MQTT_LIB_TLS)
    	struct mqtt_sec_config *tls_cfg = &(client->transport).tls.config;
    	static sec_tag_t sec_tag_list[] = { CONFIG_MQTT_TLS_SEC_TAG };
    
    	LOG_INF("TLS enabled");
    	client->transport.type = MQTT_TRANSPORT_SECURE;
    
    	tls_cfg->peer_verify = CONFIG_MQTT_TLS_PEER_VERIFY;
    	tls_cfg->cipher_count = 0;
    	tls_cfg->cipher_list = NULL;
    	tls_cfg->sec_tag_count = ARRAY_SIZE(sec_tag_list);
    	tls_cfg->sec_tag_list = sec_tag_list;
    	tls_cfg->hostname = CONFIG_MQTT_BROKER_HOSTNAME;
    
    #if defined(CONFIG_NRF_MODEM_LIB)
    	tls_cfg->session_cache = IS_ENABLED(CONFIG_MQTT_TLS_SESSION_CACHING) ?
    					    TLS_SESSION_CACHE_ENABLED :
    					    TLS_SESSION_CACHE_DISABLED;
    #else
    	/* TLS session caching is not supported by the Zephyr network stack */
    	tls_cfg->session_cache = TLS_SESSION_CACHE_DISABLED;
    
    #endif
    
    #else
    	client->transport.type = MQTT_TRANSPORT_NON_SECURE;
    #endif
    
    	return err;
    }
    
    /**@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;
    }
    
    #if defined(CONFIG_DK_LIBRARY)
    static void button_handler(uint32_t button_states, uint32_t has_changed)
    {
    	if (has_changed & button_states &
    	    BIT(CONFIG_BUTTON_EVENT_BTN_NUM - 1)) {
    		int ret;
    
    		ret = data_publish(&client,
    				   MQTT_QOS_1_AT_LEAST_ONCE,
    				   CONFIG_BUTTON_EVENT_PUBLISH_MSG,
    				   sizeof(CONFIG_BUTTON_EVENT_PUBLISH_MSG)-1);
    		if (ret) {
    			LOG_ERR("Publish failed: %d", ret);
    		}
    	}
    }
    #endif
    
    static int shell_mqtt_publish(const struct shell *shell, size_t argc, char **argv)
    {
    	ARG_UNUSED(argc);
    	ARG_UNUSED(argv);
    
    	int ret;
    
    	ret = data_publish(&client,
    			   MQTT_QOS_1_AT_LEAST_ONCE,
    			   CONFIG_BUTTON_EVENT_PUBLISH_MSG,
    			   sizeof(CONFIG_BUTTON_EVENT_PUBLISH_MSG) - 1);
    	if (ret) {
    		LOG_ERR("Publish failed: %d", ret);
    	}
    
    	return ret;
    }
    
    SHELL_STATIC_SUBCMD_SET_CREATE(mqtt_sub,
    		SHELL_CMD(publish, NULL, "Publish data to configured publish topic",
    			shell_mqtt_publish),
    		SHELL_SUBCMD_SET_END /* Array terminated. */
    );
    SHELL_CMD_REGISTER(mqtt, &mqtt_sub, "MQTT operations", NULL);
    
    /**@brief Configures modem to provide LTE link. Blocks until link is
     * successfully established.
     */
    static int modem_configure(void)
    {
    #if defined(CONFIG_LTE_LINK_CONTROL)
    	/* Turn off LTE power saving features for a more responsive demo. Also,
    	 * request power saving features before network registration. Some
    	 * networks rejects timer updates after the device has registered to the
    	 * LTE network.
    	 */
    	LOG_INF("Disabling PSM and eDRX");
    	lte_lc_psm_req(false);
    	lte_lc_edrx_req(false);
    
    	if (IS_ENABLED(CONFIG_LTE_AUTO_INIT_AND_CONNECT)) {
    		/* Do nothing, modem is already turned on
    		 * and connected.
    		 */
    	} else {
    		int err;
    
    		LOG_INF("LTE Link Connecting...");
    		err = lte_lc_init_and_connect();
    		if (err) {
    			LOG_INF("Failed to establish LTE connection: %d", err);
    			return err;
    		}
    		LOG_INF("LTE Link Connected!");
    	}
    #endif /* defined(CONFIG_LTE_LINK_CONTROL) */
    
    	return 0;
    }
    
    
    
    /**
     * @brief Function for handling TWIM driver events.
     *
     * @param[in] p_event   Event information structure.
     * @param[in] p_context General purpose parameter set during initialization of the TWIM.
     *                      This parameter can be used to pass additional information to the
     *                      handler function. In this example @p p_context is used to pass address
     *                      of TWI transfer descriptor structure.
     */
    static void twim_handler(nrfx_twim_evt_t const * p_event, void * p_context)
    {
        nrfx_err_t status;
        (void)status;
    
        nrfx_twim_xfer_desc_t * twim_desc = p_context;
        static bool m_master_done = false;
    
        if (p_event->type == NRFX_TWIM_EVT_DONE)
        {
            LOG_INF("--> Master event: done - transfer completed");
            twim_desc->type = NRFX_TWIM_XFER_RX;
            twim_desc->p_primary_buf = m_rx_buffer_master;
    
            if (!m_master_done)
            {
                status = nrfx_twim_xfer(&twim_inst, twim_desc, 0);
                NRFX_ASSERT(status == NRFX_SUCCESS);
                m_master_done = true;
            }
            else
            {
                LOG_INF("Content of master RX buffer: %s", m_rx_buffer_master);
            }
        }
        else
        {
            LOG_INF("--> MASTER handler, event: %d.", p_event->type);
        }
    }
    
    /**
     * @brief Function for handling TWIS driver events.
     *
     * @param[in] p_event Event information structure.
     */
    static void twis_handler(nrfx_twis_evt_t const * p_event)
    {
        nrfx_err_t status;
        (void)status;
    
        switch (p_event->type)
        {
            case NRFX_TWIS_EVT_WRITE_DONE:
                LOG_INF("--> Slave event: write done.");
                break;
    
            case NRFX_TWIS_EVT_READ_DONE:
                LOG_INF("--> Slave event: read done.");
                break;
    
            case NRFX_TWIS_EVT_WRITE_REQ:
                status = nrfx_twis_rx_prepare(&twis_inst, m_rx_buffer_slave, sizeof(m_rx_buffer_slave));
                NRFX_ASSERT(status == NRFX_SUCCESS);
                LOG_INF("--> Slave event: write request");
                break;
    
            case NRFX_TWIS_EVT_READ_REQ:
                status = nrfx_twis_tx_prepare(&twis_inst, m_rx_buffer_slave, sizeof(m_rx_buffer_slave));
                NRFX_ASSERT(status == NRFX_SUCCESS);
                LOG_INF("--> Slave event: read request");
                break;
    
            default:
                LOG_INF("--> SLAVE event: %d.", p_event->type);
        }
    }
    
    void mqtt_handle_thread(void) {
    	LOG_INF("The MQTT simple sample started");
    
    	uint32_t connect_attempt = 0;
    	int err;
    
    	#if defined(CONFIG_MQTT_LIB_TLS)
    	err = certificates_provision();
    	if (err != 0) {
    		LOG_ERR("Failed to provision certificates");
    		return;
    	}
    	#endif /* defined(CONFIG_MQTT_LIB_TLS) */
    		
    		do {
    			err = modem_configure();
    			if (err) {
    				LOG_INF("Retrying in %d seconds",
    					CONFIG_LTE_CONNECT_RETRY_DELAY_S);
    				k_sleep(K_SECONDS(CONFIG_LTE_CONNECT_RETRY_DELAY_S));
    			}
    		} while (err);
    
    		err = client_init(&client);
    		if (err != 0) {
    			LOG_ERR("client_init: %d", err);
    			return;
    		}
    
    	#if defined(CONFIG_DK_LIBRARY)
    		dk_buttons_init(button_handler);
    	#endif
    
    	do_connect:
    	if (connect_attempt++ > 0) {
    		LOG_INF("Reconnecting in %d seconds...",
    			CONFIG_MQTT_RECONNECT_DELAY_S);
    		k_sleep(K_SECONDS(CONFIG_MQTT_RECONNECT_DELAY_S));
    	}
    	err = mqtt_connect(&client);
    	if (err != 0) {
    		LOG_ERR("mqtt_connect %d", err);
    		goto do_connect;
    	}
    
    	err = fds_init(&client);
    	if (err != 0) {
    		LOG_ERR("fds_init: %d", err);
    		return;
    	}
    
    	while (1) {
    		err = poll(&fds, 1, mqtt_keepalive_time_left(&client));
    		if (err < 0) {
    			LOG_ERR("poll: %d", errno);
    			break;
    		}
    
    		err = mqtt_live(&client);
    		if ((err != 0) && (err != -EAGAIN)) {
    			LOG_ERR("ERROR: mqtt_live: %d", err);
    			break;
    		}
    
    		if ((fds.revents & POLLIN) == POLLIN) {
    			err = mqtt_input(&client);
    			if (err != 0) {
    				LOG_ERR("mqtt_input: %d", err);
    				break;
    			}
    		}
    
    		if ((fds.revents & POLLERR) == POLLERR) {
    			LOG_ERR("POLLERR");
    			break;
    		}
    
    		if ((fds.revents & POLLNVAL) == POLLNVAL) {
    			LOG_ERR("POLLNVAL");
    			break;
    		}
    	}
    
    	LOG_INF("Disconnecting MQTT client...");
    
    	err = mqtt_disconnect(&client);
    	if (err) {
    		LOG_ERR("Could not disconnect MQTT client: %d", err);
    	}
    	goto do_connect;
    }
    
    void main(void)
    {
    	nrfx_err_t status;
    	(void)status;
    	LOG_INF("Starting nrfx_twim_twis non-blocking example.");
    	nrfx_twim_xfer_desc_t twim_xfer_desc = NRFX_TWIM_XFER_DESC_TX(SLAVE_ADDR,
                                                                      m_tx_buffer_master,
                                                                      sizeof(m_tx_buffer_master));
    	nrfx_twim_config_t twim_config = NRFX_TWIM_DEFAULT_CONFIG(MASTER_SCL_PIN, MASTER_SDA_PIN);
        status = nrfx_twim_init(&twim_inst, &twim_config, twim_handler, &twim_xfer_desc);
    	nrfx_twis_config_t twis_config = NRFX_TWIS_DEFAULT_CONFIG(SLAVE_SCL_PIN,
                                                                  SLAVE_SDA_PIN,
                                                                  SLAVE_ADDR);
    	status = nrfx_twis_init(&twis_inst, &twis_config, twis_handler);
    	
    	#if defined(__ZEPHYR__)
            #define TWIM_INST         NRFX_CONCAT_2(NRF_TWIM, TWIM_INST_IDX)
            #define TWIM_INST_HANDLER NRFX_CONCAT_3(nrfx_twim_, TWIM_INST_IDX, _irq_handler)
            IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(TWIM_INST), IRQ_PRIO_LOWEST, TWIM_INST_HANDLER, 0);
    
            #define TWIS_INST         NRFX_CONCAT_2(NRF_TWIS, TWIS_INST_IDX)
            #define TWIS_INST_HANDLER NRFX_CONCAT_3(nrfx_twis_, TWIS_INST_IDX, _irq_handler)
            IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(TWIS_INST), IRQ_PRIO_LOWEST, TWIS_INST_HANDLER, 0);
        #endif
    
    	nrfx_twim_enable(&twim_inst);
    	nrfx_twis_enable(&twis_inst);
    	status = nrfx_twim_xfer(&twim_inst, &twim_xfer_desc, 0);
    
    	while (1)
    	{
    		LOG_INF("Messagetest");
    		LOG_INF("Message to send: %s", m_tx_buffer_master);
    		LOG_INF("Content of master RX buffer: %s", m_rx_buffer_master);
    		k_sleep(K_SECONDS(2));
    	}
    	
    }
    
    K_THREAD_DEFINE(mqtt_handle_thread_1, 2048, mqtt_handle_thread, NULL, NULL, NULL, 5, 0, 0);
    

    Thanks for the help everyone.

  • Hey again,

    I'm really glad I could help! Keep on developing!

    -Torje

Related