Topic MQTT subscription callback

Hi!

General premises:

I’m programming an Espressif microcontroller, the esp32-wroom-32, and I’ve followed the getting started guide (https://docs.aws.amazon.com/it_it/freertos/latest/userguide/getting_started_espressif.html) and downloaded the amazon-freertos directory with all the demos and specific vendors folders.

I’ve tested the MQTT, HTTPS Upload Async and HTTPS Download Async demos succesfully. But I need my own demo, so I’ve created a “my_demo” folder inside “demos” folder where I’ve put my file “iot_my_demo.c”, mantaining the structure of the directories. In this file I have the demo entry function “RunMyDemo” called by “iot_demo_freertos.c”, where I have a state machine to handle a Uart communication with another host. I’ve tried to copy all the demo entry function of MQTT and HTTPS demos (RunMqttDemo, RunHttpsAsyncUploadDemo, RunHttpsAsyncDownloadDemo) and call them in some states of my state machine and it works. I’m able, on commands arriving from Uart, to publish data into topics and to download or upload towards Amazon S3. So I succeeded to replicate the behavior of the demos merging them into a single file.

Note: with my state machine I connect to Wi-Fi only once and I reuse the same Network information for all demos function (MQTT, HTTPS).

I have 1 issue:

It is related to topic subscription callback; the MQTT demo code establishes the MQTT connection, subscribes into topics, publishes into the same topics and waits for incoming publish messages, as it knows the number of messages published it waits to receive all messages and finally the demo disconnects the MQTT connection. With the demo code I’m able to see the subscription callback call when it publishes into topics (I see on serial debug some IotLogInfo, for example the payload of the publish message received…).
But then I’ve tried to separate the MQTT connection, disconnection, publish, subscribe, desubscribe, making functions for each of them and a single global variable “IotMqttConnection_t mqttConnectionHandle = IOT_MQTT_CONNECTION_INITIALIZER;” to handle the MQTT connection.
With this approach I’ve succesfully tried (on commands from Uart) to connect to MQTT broker, to publish into topic (seeing the messages from the IoT Core console), to sub or desub to topics and to disconnect from MQTT broker when I want. But when I succesfully subscribe to a topic, calling the “_modifySubscriptions” function I add the “_mqttSubscriptionCallback” to the “IotMqttSubscription_t pSubscriptions[ TOPIC_FILTER_COUNT ] = { IOT_MQTT_SUBSCRIPTION_INITIALIZER };” with “pSubscriptions[ i ].callback.function = _mqttSubscriptionCallback;” and “pSubscriptions[ i ].callback.pCallbackContext = pCallbackParameter;”.
But the callback seems that is never invoked. In effect I succesfully subscribe to a topic (“test/w-block-interation”), but trying to publish to the same topic from the MQTT client provided by AWS IoT Core console, I never see some response on my monitor serial debug, as I saw trying the demo code with some print about the incoming publish messages.
In the following image I’ve reported my “_modifySubscriptions” initial code.

Thanks in advance for your attention.

Hi @Luca, to better understand the problem, can you share all the places of modification of the source taken from the iot_demo_mqtt.c file either as text or as a file attachment to the thread?
The uploaded image does not show the entire definition of _mqttSubscrptionCallback and I’m unable to see any changes for function for the lines shown in the image from the official version on our GitHub repository besides the debug print statement added on line 1237.

But then I’ve tried separate the MQTT connection, disconnection, publish, subscribe, desubscribe, making functions for each of them and a single global variable “IotMqttConnection_t mqttConnectionHandle = IOT_MQTT_CONNECTION_INITIALIZER;” to handle the MQTT connection

Can you also explain what you mean by the above for the changes you made?

Hi @aws-archit

I’m sorry for the quick explanation. I mean that the “iot_demo_mqtt.c” code establishes the MQTT connection using the handler (“IotMqttConnection_t mqttConnection = IOT_MQTT_CONNECTION_INITIALIZER;”) defined locally in the “RunMqttDemo” function, that is the entry function for the demo, and once it opens the connection, it subscribes to topics and publishes to the same topics, waiting for all the incoming publish messages. And finally the demo calls the “IotMqtt_Disconnect” function.
I have instead defined the handler (which I called mqttConnectionHandle) globally, and once I establish the MQTT connection, I reuse such handler to publish, subscribe, desubscribe to topics in different times.
My code has a state machine where, once the Wi-Fi and then MQTT connection are established, i loop into an idle state waiting for commands from Uart (commands for publish into a topic, subscribe to topics, download files from S3…).

I solved the issue by adding “IotClock_SleepMs( 50 );” into the idle state of my state machine.
I think the problem was that the MQTT task was never woke up when my MQTT agent received the messages from the network, and it was woken up only when I did MQTT API calls.
I’m able now to see on my serial debug the information printed by the “_mqttSubscrptionCallback” when I try to publish to the topic to which I subscribed, from the IoT Core Test console, so the callback is now correctly invoked on incoming publish messages.

Thanks for your attention,
Best regards

Hi @Luca, thanks for providing explanation on changes made for your demo setup.
I am glad to know that the issue is resolved for you.

I want to mention that the iot_demo_mqtt.c demo uses a semaphore to notify about the arrival of the incoming PUBLISH messages. The logic for the timed wait on the semaphore notification resides in the _publishAllMessages function

1 Like