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

mqtt, topics

Hello,

I am having some trouble retrieving the mqtt topic which are published on, and the data within.

I've used the mqtt_simple as a starting point.

static int subscribe(void)
{
                
        memset(example, 0, sizeof(example));
        memset(example1, 0, sizeof(example1));
        memset(example2, 0, sizeof(example2));
        fetch_topic();

        strcpy(example1, example);
        strcpy(example2, example);

        strcat(example, "/fota");
        strcat(example1, "/position");
        strcat(example1, "/status");
        strcat(example2, "/position");

        printf(example);
        printf(example1);
        printf(example2);

	struct mqtt_topic subscribe_topics[] = {
		{
		    .topic = {
			    .utf8 = example,
			    .size = strlen(example)
		    },
		    .qos = MQTT_QOS_1_AT_LEAST_ONCE
		},
        	{
		    .topic = {
			    .utf8 = example1,
			    .size = strlen(example1)
		    },
		    .qos = MQTT_QOS_1_AT_LEAST_ONCE
		},
        	{
		    .topic = {
			    .utf8 = example2,
			    .size = strlen(example2)
		    },
		    .qos = MQTT_QOS_1_AT_LEAST_ONCE
		}
	};

	const struct mqtt_subscription_list subscription_list = {
		.list = subscribe_topics,
		.list_count = ARRAY_SIZE(subscribe_topics),
		.message_id = 1234
	};

	printk("Subscribing to: %s len %u\n", example,
		(unsigned int)strlen(example));
        printk("Subscribing to: %s len %u\n", example1,
		(unsigned int)strlen(example1));
        printk("Subscribing to: %s len %u\n", example2,
		(unsigned int)strlen(example2));

	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)
{
        memset(payload_buf, 0, sizeof(payload_buf));
	uint8_t *buf = payload_buf;
	uint8_t *end = buf + length;

	if (length > sizeof(payload_buf)) {
		return -EMSGSIZE;
	}

	while (buf < end) {
		int ret = mqtt_read_publish_payload(c, buf, end - buf);

		if (ret < 0) {
			int err;

			if (ret != -EAGAIN) {
				return ret;
			}

			printk("mqtt_read_publish_payload: EAGAIN\n");

			err = poll(&fds, 1,
				   CONFIG_MQTT_KEEPALIVE * MSEC_PER_SEC);
			if (err > 0 && (fds.revents & POLLIN) == POLLIN) {
				continue;
			} else {
				return -EIO;
			}
		}

		if (ret == 0) {
			return -EIO;
		}

		buf += ret;
	}

	return 0;
}

/**@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) {
			printk("MQTT connect failed %d\n", evt->result);
			break;
		}

		printk("[%s:%d] MQTT client connected!\n", __func__, __LINE__);

#if defined(CONFIG_MQTT_LIB_TLS)
		printk("Connected with TLS\n");
#endif
                
		subscribe();

		break;

	case MQTT_EVT_DISCONNECT:
		printk("[%s:%d] MQTT client disconnected %d\n", __func__,
		       __LINE__, evt->result);

		break;

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

		printk("[%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);
                        printk("len=%d\n", p->message.payload.len);
                        

                        printk("Topic: %s\n", evt->param.publish.message);


			/* Echo back received data */

			/*
                        data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,
				payload_buf, p->message.payload.len);
                        */
                        
		} else {
			printk("mqtt_read_publish_payload: Failed! %d\n", err);
			printk("Disconnecting MQTT client...\n");

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

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

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

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

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

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

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

/**@brief Resolves the configured hostname and
 * initializes the MQTT broker structure
 */

I managed to printk, the momentary topic, used with : printk("Topic: %s\n", evt->param.publish.message);

If I publish to another topic, which is longer in size, the result will look like this : 

Topic: es400/89470060190924044097/position/status


[mqtt_evt_handler:572] MQTT PUBLISH result=0 len=1


Received: K


len=1


Topic: es400/89470060190924044097/fotation/status
[mqtt_evt_handler:572] MQTT PUBLISH result=0 len=1
Received: K


len=1

---
I need a way to store the topic so that I can differenciate between the published topic, and also store the data within a variable for later use.

Any ideas will be appreciated.

Regards, David
Parents
  • Hi David,

    I need a way to store the topic so that I can differenciate between the published topic, and also store the data within a variable for later use.

     Where do you want to store the topic and data?


    Or do you plan to connect the nrf9160 device to a computer and print/send topic and data over to the computer?


    Usually when sending data form the nrf9160 over mqtt to som other service like a cloud that subscribes to the topics the nrf9160 publishes data to, the data is stored not on the nrf9160 device but on some sever somewhere. 

    Here is a guide to one possible way to save the data and topics for later use using AWS. There are other guides, blog posts and tutorials here on devzone that might be helpful.

    Regards,
    Jonathan

Reply
  • Hi David,

    I need a way to store the topic so that I can differenciate between the published topic, and also store the data within a variable for later use.

     Where do you want to store the topic and data?


    Or do you plan to connect the nrf9160 device to a computer and print/send topic and data over to the computer?


    Usually when sending data form the nrf9160 over mqtt to som other service like a cloud that subscribes to the topics the nrf9160 publishes data to, the data is stored not on the nrf9160 device but on some sever somewhere. 

    Here is a guide to one possible way to save the data and topics for later use using AWS. There are other guides, blog posts and tutorials here on devzone that might be helpful.

    Regards,
    Jonathan

Children
No Data
Related