Subscribing to Topics in MQTT
As you may know, for receiving data in MQTT your device needs to be subscribed to a topic. To do that, you will need to send a subscribe packet to your broker. For app_mqttExampleInit(), you need to create a subscribe packet, and then execute MQTT_TransmissionHandler(mqttConnnectionInfo) to send it.
Create Subscribe Packet
In the generated example, there’s no function for creating a subscribe packet. So, instead, you can copy this one at the top of mqtt_example.c:
{
mqttSubscribePacket subscribe_packet;
//fill the whole packet with 0:
memset(&subscribe_packet, 0, sizeof(mqttSubscribePacket));
subscribe_packet.subscribePayload->topic = topic;
subscribe_packet.subscribePayload->topicLength = strlen(subscribe_packet.subscribePayload->topic);
subscribe_packet.subscribePayload->requestedQoS = 0;
subscribe_packet.packetIdentifierLSB = 1;
subscribe_packet.packetIdentifierMSB = 0;
MQTT_CreateSubscribePacket(&subscribe_packet);
}
This function just sets the parameters for the MQTT_CreateSubscribePacket() function, which will set the needed variables for creating a Subscribe packet to be sent. The only variable that you will need to choose is “topic”, which will be the topic that you want to subscribe to.
Send Subscribe Packet
Write these two lines in the SUBSCRIBING state for sending subscribe packets:
MQTT_TransmissionHandler(mqttConnnectionInfo);
Then declare “t” as an array of uint8_t elements in mqtt_example.c. “t” will be the name of the topic that the device will subscribe to. For example:
uint8_t t[] = "subscribing/topic";
Your device should now continuously subscribe, but you are making too many attempts. At some time, your program should collapse. This is explained in the next section.
Subscribe Just Once
It is recommended to only subscribe once. Doing it more than once would be useless unless you want to subscribe to different topics. Also, it is recommended to wait until the device has initialized everything, otherwise, it may not work.
Every time that you subscribe, you receive a Suback packet. You will need to process the Suback packet. This is explained in the next section, “Add receiving, processing and reading packets”. If you don’t process the Suback, the program won’t create more subscribe packets, and your program will end up collapsing. Try to execute the program to see what happens by yourself. You should see this if you are using Eclipse Mosquitto™:
The solution is to subscribe just once per topic, once the program has been fully initialized, and then receive and process the Suback packet. Once Suback has been processed, the program will try to subscribe again. You can add some lines to avoid it. Subscribing more than once to the same topic or subscribing before the program has been fully initialized shouldn’t be harmful, but the program would be more likely to crash.
In this example, to measure if the program is fully initialized, we create the only_once variable, where we would save how many times appMQTTPublishTimeoutOccured was true. This is, how many times the timer has been completed. When only_once is 3, this is, when the timer has been completed three times, we consider that the device is fully initialized and subscribed.
uint8_t only_once=0; //counts how many times the timer was completed
{
if(appMQTTPublishTimeoutOccured == true) //checks if timer was completed
{
only_once++; //counts how many times the timer was completed
if (only_once==3){ //if timer was completed 3 times, subscribe
create_MQTT_subscribe_packet(t);
MQTT_TransmissionHandler(mqttConnnectionInfo);
only_once=4; //to avoid only_once overflow and reset to be 3 again
}
}
changeState(PUBLISHING);
}
The final state should be like the command prompt showed before, but without the client being disconnected: