3.1.7.2 MQTT Service
The Cloud service provides an Application Programming Interface (API) to manage MQTT functionalities. These functionalities include, configuring MQTT broker for connection, disconnection events, re-connecting to MQTT broker, publishing, subscribing and setting callbacks.
MQTT service (only v1.0.0) provides support for Azure Device Provisioning Service (DPS).
Azure DPS implementation in the MQTT service layer, simplifies device connectivity with
Azure IoT HUB. In this case, user application only provides Azure IoT central connection
parameters and final IoT HUB connection status is reported through the registered
callback function.
Note: MCC Melody based MQTT service (latest release v2.0.0) currently
enables connection with Azure IoT Hub without Azure DPS and IoT central
connection.
The MQTT service API example is as follows:
The following list captures the MQTT callback event codes and their
arguments
RNWF_RESULT_t RNWF_MQTT_SrvCtrl( RNWF_MQTT_SERVICE_t request, void *input)
It
handles following services and reports the result to application over the return code or
through the registered callback:Service | Input | Description |
---|---|---|
RNWF_MQTT_CONFIG | Broker URL, Port, Client ID, Username, TLS configuration | Configures the MQTT server details along with the corresponding TLS configurations |
RNWF_MQTT_CONNECT | None | Initiates the MQTT connection to the configured MQTT broker |
RNWF_MQTT_RECONNECT | None | Triggers the re-connection to the configured MQTT broker |
RNWF_MQTT_DISCONNECT | None | Disconnects from the connected MQTT broker |
RNWF_MQTT_SUBSCRIBE_QOS0 | Subscribe topic (String) | Subscribes to the given subscribe topic with QoS0 |
RNWF_MQTT_SUBSCRIBE_QOS1 | Subscribe topic (String) | Subscribes to the given subscribe topic with QoS1 |
RNWF_MQTT_SUBSCRIBE_QOS2 | Subscribe topic (String) | Subscribes to the given subscribe topic with QoS2 |
RNWF_MQTT_PUBLISH | New, QOS, Retain, topic, message | Publish the message on given publish topic and configuration |
RNWF_MQTT_SET_CALLBACK | Callback Function Handler | Registers the MQTT callback to report the status to user application |
Event | Response Components | Comments |
---|---|---|
RNWF_MQTT_CONNECTED | None | Reported once connected to MQTT broker |
RNWF_MQTT_DISCONNECTED | None | Event to report the MQTT broker disconnection |
RNWF_MQTT_SUBCRIBE_MSG | dup, QoS, retain, topic, payload | Reports the received payload for the subscribed topic |
RNWF_MQTT_SUBCRIBE_ACK | Integer string | Subscribe ack return code |
RNWF_MQTT_DPS_STATUS (Applicable only in MCC
Melody based MQTT Service v1.0.0) | Integer | Azure DPS status:-
|
The sequence chart below explains this process.
MQTT Publish
MQTT Subscribe
The sequence for subscribing to a topic from the MQTT Broker is illustrated below. The
user application needs to use the API to subscribe to the topic with the appropriate QoS
value.
RNWF_MQTT_SrvCtrl(RNWF_MQTT_SUBSCRIBE_QOS0, buffer)
An example of the MQTT application provided below showcases the use of MQTT service
API's:
/*
This is ONLY an example for MQTT application - "rnwf02_app.c"
*/
#include "rnwf_app.h"
#include "rnwf_wifi_service.h"
#include "rnwf_mqtt_service.h"
/* feature addition from FW v2.0.0*/
/* Holds IP address of the device */
static uint8_t g_DevIp[50];
/* feature addition from FW v2.0.0*/
static uint8_t isSockOpen = 0; //guard condition to open a socket
/* MQTT Connection States */
#define MQTT_DISCONNECTED 0
#define MQTT_CONNECTING 1
#define MQTT_CONNECTED 2
uint8_t g_isMqttConnected = MQTT_DISCONNECTED;
/* Application buffer */
uint8_t app_buf[APP_BUFFER_SIZE_MAX];
static uint8_t subCnt;
/* MQTT Subscribe Topic Name List */
static const char *subscribe_list[] = {"mchp/rnwf02/to", NULL, NULL, NULL, NULL};
RNWF_MQTT_CFG_t mqtt_cfg = {
.url = "test.mosquitto.org",
.clientid = CLIENT_ID,
.username = "",
.password = "",
.port = 1883,
.azure_dps = 0
};
void APP_Cloud_SUB_Handler(char *p_str)
{
if(p_str != NULL) {
DBG_MSG_MQTT("RNWF02 <- %s\r\n", p_str);
} else {
DBG_MSG_MQTT("%s\r\n", p_str);
}
return;
}
void APP_Cloud_SUBACK_Handler(void)
{
if(subscribe_list[subCnt] != NULL)
{
sprintf(app_buf, "%s", subscribe_list[subCnt++]);
RNWF_MQTT_SrvCtrl(RNWF_MQTT_SUBSCRIBE_QOS0, app_buf);
}
return;
}
void APP_Cloud_Task(void)
{
/* Implement app specific MQTT_Task() method here */
/* Call periodically at telemetry rate */
uint8_t pub_buf[64];
static uint32_t pub_cnt = 0;
if(/*condition to check if telemetry rate is elapsed*/)
{
pub_cnt++;
sprintf(pub_buf, "RNWF -> Msg #%d", pub_cnt);
APP_MQTT_Publish(MQTT_PUB_TOPIC, pub_buf);
}
return;
}
RNWF_RESULT_t APP_MQTT_Publish(const char *top, const char *msg)
{
RNWF_MQTT_FRAME_t mqtt_pub;
mqtt_pub.isNew = NEW_MSG;
mqtt_pub.qos = MQTT_QOS0;
mqtt_pub.isRetain = NO_RETAIN;
mqtt_pub.topic = top;
mqtt_pub.message = msg;
return RNWF_MQTT_SrvCtrl(RNWF_MQTT_PUBLISH, (void *)&mqtt_pub);
}
RNWF_RESULT_t APP_MQTT_Callback(RNWF_MQTT_EVENT_t event, uint8_t *p_str)
{
switch(event)
{
case RNWF_MQTT_CONNECTED:
{
printf("\n\rMQTT Connected\r\n");
g_isMqttConnected = MQTT_CONNECTED;
APP_MQTT_Publish(MQTT_PUB_TOPIC, "RNWF02 -> I am Up!");
if(subscribe_list[subCnt] != NULL)
{
sprintf(app_buf, "%s", subscribe_list[subCnt++]);
RNWF_MQTT_SrvCtrl(SUBSCRIBE_QOS_VALUE, app_buf);
}
}
break;
case RNWF_MQTT_SUBCRIBE_ACK:
{
APP_Cloud_SUBACK_Handler();
}
break;
case RNWF_MQTT_SUBCRIBE_MSG:
{
printf("RNWF02 <- %s\r\n", p_str);
APP_Cloud_SUB_Handler(p_str);
}
break;
case RNWF_MQTT_DISCONNECTED:
{
printf("MQTT - Reconnecting...\r\n");
g_isMqttConnected = MQTT_DISCONNECTED;
RNWF_MQTT_SrvCtrl(RNWF_MQTT_CONNECT, NULL);
g_isMqttConnected = MQTT_CONNECTING;
}
break;
default:
break;
}
return RNWF_PASS;
}
void APP_WIFI_Callback(RNWF_WIFI_EVENT_t event, uint8_t *p_str)
{
switch(event)
{
case RNWF_SNTP_UP:
{
break;
}
case RNWF_CONNECTED:
{
printf("Wi-Fi Connected\n");
break;
}
case RNWF_DISCONNECTED:
{
printf("Wi-Fi Disconnected\nReconnecting... \n");
RNWF_WIFI_SrvCtrl(RNWF_STA_CONNECT, NULL);
break;
}
case RNWF_DHCP_IPV4_DONE:
{
printf("\n\rDHCP IPv4: %s\n\r", &p_str[2]);
if(isSockOpen == 0)
{
RNWF_MQTT_SrvCtrl(RNWF_MQTT_SET_CALLBACK, APP_MQTT_Callback);
RNWF_MQTT_SrvCtrl(RNWF_MQTT_CONFIG, (void *)&mqtt_cfg);
RNWF_MQTT_SrvCtrl(RNWF_MQTT_CONNECT, NULL);
isSockOpen = 1;
}
break;
}
case RNWF_DHCP_LINK_LOCAL_IPV6_DONE:
{
printf("\n\rDHCP link-local IPv6:%s\n\r", &p_str[2]);
break;
}
case RNWF_DHCP_GLOBAL_IPV6_DONE:
{
printf("\n\rDHCP global IPv6:%s\n\r", &p_str[2]);
break;
}
case RNWF_SET_REGDOM:
{
RNWF_WIFI_SrvCtrl(RNWF_SET_WIFI_REGDOM, (void *)COUNTRY_CODE);
break;
}
case RNWF_SCAN_INDICATION:
{
break;
}
case RNWF_SCAN_DONE:
{
break;
}
case RNWF_CONNECT_FAILED:
{
break;
}
default:
{
break;
}
}
}
void RNWF_APP_Initialize(void)
{
/* Wi-Fi Connectivity */
RNWF_WIFI_PARAM_t wifi_sta_cfg = {RNWF_WIFI_MODE_STA, HOME_AP_SSID, HOME_AP_PASSPHRASE, HOME_AP_SECURITY, STA_AUTOCONNECT};
printf("Connecting to %s\r\n", HOME_AP_SSID);
RNWF_WIFI_SrvCtrl(RNWF_WIFI_SET_CALLBACK, APP_WIFI_Callback);
RNWF_WIFI_SrvCtrl(RNWF_SET_WIFI_PARAMS, &wifi_sta_cfg);
/* RNWF Application Callback register */
while(1)
{
if(g_isMqttConnected == MQTT_CONNECTED)
{
APP_Cloud_Task();
}
RNWF_EVENT_Handler();
}
}