IMqttClient
is a MQTT 5 client interface.
Note: Only MQTT version 5 is officially supported.
WebSocket transport is not supported. For more information, refer to
MQTT v5.0 spec
.
File | common/interface/mqtt_client.h |
Public functions |
Create MQTTConnect MQTTSubscribe MQTTPublish MQTTUnsubscribe MQTTPing MQTTDisconnect MQTTSendAuthData GetAliasByTopicName GetNameByTopicAlias |
Classes |
IMqttClient UMqttClient |
Data types |
MqttError MQTTReasonCode MQTTAuthReasonCode MQTTClientDisconnectReason |
Examples |
Code Example |
class IMqttClient {
public:
static IMqttClient* Create(class IIoMux* const iomux,
class ISocketProvider* const tcpSocketProvider,
class ISocketProvider* const tlsSocketProvider,
class UMqttClient* const user,
class IInstanceLog* const log,
class IDns* const dns);
virtual MqttError MQTTConnect(const char* broker,
char* outputClientId,
size_t outputClientIdSize,
word port = 1883,
bool tls = false,
const char* payloadUserName = nullptr,
const byte* payloadPassword = nullptr,
word payloadPasswordSize = 0,
const char* inputClientId = nullptr,
word keepAlive = 0,
const char* willTopic = nullptr,
const byte* willPayload = nullptr,
word willPayloadSize = 0,
byte willQoS = 0,
bool willRetain = false,
const char* userPropertyName = nullptr,
const char* userPropertyValue = nullptr,
dword sessionExpiryInterval = 0,
const char* authenticationMethod = nullptr,
const byte* authenticationData = nullptr,
word authenticationDataSize = 0,
word reciveMaximum = 65535,
dword maximumPacketSize = 65535,
word topicAliasMaximum = 0,
bool requestResponseInformation = 0,
bool requestProblemInformation = 1,
dword willDelayInterval = 0,
bool payloadFormatIndicator = 0,
dword messageExpiryInterval = 0,
const char* contentType = nullptr,
const char* responseTopic = nullptr,
const byte* correlationData = nullptr,
word correlationDataSize = 0,
const char* payloadUserPropertyName = nullptr,
const char* payloadUserPropertyValue = nullptr) = 0;
virtual MqttError MQTTSubscribe(word subscriptionIdentifier,
const char* topicFilter,
const char* qosLevels = nullptr,
const char* noLocalFlags = nullptr,
const char* retainFlags = nullptr,
const char* retainHandlingFlags = nullptr) = 0;
virtual MqttError MQTTPublish(const char* topicName,
byte QoS = 0,
word topicAlias = 0,
const byte* payload = nullptr,
size_t payloadSize = 0,
const char* contentType = nullptr,
bool retain = false,
const char* userPropertyName = nullptr,
const char* userPropertyValue = nullptr,
dword messageExpiryInterval = 0,
const char* responseTopic = nullptr,
const byte* correlationData = nullptr,
word correlationDataSize = 0) = 0;
virtual MqttError MQTTUnsubscribe(const char* topicFilter,
const char* userPropertyName = nullptr,
const char* userPropertyValue = nullptr) = 0;
virtual MqttError MQTTPing() = 0;
virtual MqttError MQTTDisconnect(MQTTClientDisconnectReason reason = NormalDisconnection,
dword sessionExpiryInterval = 0,
const char* reasonString = nullptr,
const char* userPropertyname = nullptr,
const char* userPropertyValue = nullptr,
const char* serverReference = nullptr) = 0;
virtual MqttError MQTTSendAuthData(const char* authenticationMethod,
const byte* authenticationData,
word authenticationDataSize,
MQTTAuthReasonCode reasonCode = MQTTAuthReasonCode::ContinueAuthentication,
const char* reasonString = nullptr,
const char* userPropertyName = nullptr,
const char* userPropertyValue = nullptr) = 0;
virtual word GetAliasByTopicName(const char* topicName) const = 0;
virtual const char* GetNameByTopicAlias(word alias) const = 0;
};
This class is the main interface for MQTT client functionality. It allows connecting to a broker via either TCP or TLS socket, publishing and subscribing to one or multiple topics (separated by commas), sending pings, handling authentication, and more. The ClientId can either be generated if nothing is passed, or an explicit ClientId can be used if provided. If you want to generate an ID, be sure to pass a buffer of at least 24 bytes because the generated ID is 23 bytes plus the null terminator.
Subscription Identifiers: When subscribing, a subscription identifier can be provided (e.g., 12
).
The user of this interface should store these identifiers to handle incoming messages properly.
QoS: Allowed values are 0, 1, or 2. If another value is used, the function returns IncorrectValue
.
User Properties: Can be provided with comma-separated names and comma-separated values. They correspond index-wise,
e.g. userProp1,userProp2
for names and val1,val2
for values. Each name must have a matching value.
A mismatch in the count (e.g., two names, one value) leads to an error.
Topic Aliases: You can use topicAlias
to assign or reuse aliases. If a topic alias already exists, you can publish with the same alias
to avoid resending the full topic name. (Details are described in the MQTT v5 specification.)
IMqttClient
instance.
IIoMux * const iomux | The iomux instance needed for socket communication. |
ISocketProvider * const tcpSocketProvider | A socket provider to create a TCP socket for MQTT transport. |
ISocketProvider * const tlsSocketProvider | A socket provider to create a TLS socket for secured MQTT (MQTT over TLS). |
UMqttClient * const user | An UMqttClient instance to receive callbacks from IMqttClient . |
IInstanceLog * const log | The log instance for logging. |
IDns * const dns | An optional DNS instance for DNS resolution. |
IMqttClient*
instance. Must be deleted if no longer used.
true
and connect to the corresponding port (e.g., 8883).
const char * broker | The broker address or hostname. |
char * outputClientId | A buffer to store the generated or used client ID. If generating an ID, pass at least 24 bytes. |
size_t outputClientIdSize | Size of the outputClientId buffer. |
word port | (Default: 1883) The port number for MQTT connection. Typical default for TLS is 8883. |
bool tls | (Default: false) Set to true to enable TLS connection. |
const char* payloadUserName | (Default: nullptr) The username for MQTT connection (if any). |
const byte* payloadPassword | (Default: nullptr) The password as binary data (if any). |
word payloadPasswordSize | (Default: 0) The size of the binary password buffer. |
const char* inputClientId | (Default: nullptr) If specified, the client ID used for the MQTT connection. If null, a client ID may be generated. |
word keepAlive | (Default: 0) MQTT keep-alive interval in seconds (0 means no keep-alive required). |
const char* willTopic | (Default: nullptr) The topic for the Last Will and Testament message. |
const byte* willPayload | (Default: nullptr) The payload for the Last Will message. |
word willPayloadSize | (Default: 0) The size of the Will message payload. |
byte willQoS | (Default: 0) QoS level for Will message (0, 1, or 2). |
bool willRetain | (Default: false) If true , the Will message is retained by the broker. |
const char* userPropertyName | (Default: nullptr) Optional user property name. |
const char* userPropertyValue | (Default: nullptr) Optional user property value. |
dword sessionExpiryInterval | (Default: 0) The session expiry interval for the connection (0 means no session expiry). |
const char* authenticationMethod | (Default: nullptr) The authentication method. |
const byte* authenticationData | (Default: nullptr) Binary authentication data. |
word authenticationDataSize | (Default: 0) The size of the authentication data. |
word reciveMaximum | (Default: 65535) The receive maximum for inbound QoS 1 or 2 publishes. |
dword maximumPacketSize | (Default: 65535) The maximum packet size the client is willing to accept. |
word topicAliasMaximum | (Default: 0) The max number of aliases the client supports. |
bool requestResponseInformation | (Default: 0) If true , the server should return response information. |
bool requestProblemInformation | (Default: 1) If false , the server may reduce the amount of error information returned. |
dword willDelayInterval | (Default: 0) The delay (in seconds) before the broker publishes the Will message. |
bool payloadFormatIndicator | (Default: 0) Indicates the format of the Will message payload (UTF-8 or binary). |
dword messageExpiryInterval | (Default: 0) How long a message is stored by the broker (in seconds). |
const char* contentType | (Default: nullptr) The content type of the Will message payload. |
const char* responseTopic | (Default: nullptr) A topic to direct responses to for request/response scenarios. |
const byte* correlationData | (Default: nullptr) Used by request/response to correlate the request and response messages. |
word correlationDataSize | (Default: 0) The size of the correlation data. |
const char* payloadUserPropertyName | (Default: nullptr) An optional user property name for the Will message. |
const char* payloadUserPropertyValue | (Default: nullptr) An optional user property value for the Will message. |
MqttError
indicating success or a specific error reason.
"test/light1, test/light2"
.
QoS can be specified with a similarly comma-separated list, e.g. "0, 2"
, to match the topics in order.
word subscriptionIdentifier | Subscription identifier. The user should store this to correlate incoming messages. |
const char * topicFilter | The topic filter(s) to subscribe to, separated by commas if more than one. |
const char * qosLevels | (Default: nullptr) A comma-separated string for QoS levels corresponding to each topic, e.g. "0,1" . |
const char * noLocalFlags | (Default: nullptr) If used, a comma-separated string describing whether No Local is set (0 or 1) for each subscription. |
const char * retainFlags | (Default: nullptr) A comma-separated string describing if Retain As Published is set (0 or 1) for each subscription. |
const char * retainHandlingFlags | (Default: nullptr) A comma-separated string describing how retained messages are handled on subscribe (0,1,2) for each topic. |
MqttError
indicating success or a specific error reason.
const char * topicName | The topic(s) to publish to, separated by commas if more than one. |
byte QoS | (Default: 0) QoS level (0, 1, or 2). Can be comma-separated if multiple topics are given. |
word topicAlias | (Default: 0) A topic alias if supported. Use 0 if no alias is used. |
const byte* payload | (Default: nullptr) Pointer to the binary data to send as payload. |
size_t payloadSize | (Default: 0) The length of the payload data. |
const char* contentType | (Default: nullptr) Content type of the message payload. |
bool retain | (Default: false) If true , the broker retains the message. |
const char* userPropertyName | (Default: nullptr) An optional user property name (can be comma-separated if multiple are used). |
const char* userPropertyValue | (Default: nullptr) An optional user property value (comma-separated, matching the name list in order). |
dword messageExpiryInterval | (Default: 0) The time in seconds after which the broker will drop the message if not delivered. |
const char* responseTopic | (Default: nullptr) A topic to direct responses to for request/response scenarios. |
const byte* correlationData | (Default: nullptr) Binary data used to correlate request/response messages. |
word correlationDataSize | (Default: 0) The size of the correlation data. |
MqttError
indicating success or a specific error reason.
const char* topicFilter | The topic filter(s) to unsubscribe from, separated by commas if more than one. |
const char* userPropertyName | (Default: nullptr) An optional user property name, can be comma-separated if multiple are used. |
const char* userPropertyValue | (Default: nullptr) An optional user property value, can be comma-separated, matching the names in order. |
MqttError
indicating success or a specific error reason.
MqttError
indicating success or a specific error reason.
MQTTClientDisconnectReason reason | (Default: NormalDisconnection) The disconnection reason code. |
dword sessionExpiryInterval | (Default: 0) The session expiry interval the client wants to set on disconnect. |
const char* reasonString | (Default: nullptr) A human-readable reason string. |
const char* userPropertyname | (Default: nullptr) A user property name. |
const char* userPropertyValue | (Default: nullptr) A user property value. |
const char* serverReference | (Default: nullptr) An optional server reference, e.g., used by the broker for redirection. |
MqttError
indicating success or a specific error reason.
const char* authenticationMethod | The authentication method (must match the one set during MQTTConnect if used). |
const byte* authenticationData | The binary authentication data to send. |
word authenticationDataSize | The size of the authentication data buffer. |
MQTTAuthReasonCode reasonCode | (Default: ContinueAuthentication) The reason code for sending the auth packet. |
const char* reasonString | (Default: nullptr) An optional human-readable string describing the reason. |
const char* userPropertyName | (Default: nullptr) A user property name (comma-separated if more than one). |
const char* userPropertyValue | (Default: nullptr) A user property value (comma-separated, matching names). |
MqttError
indicating success or a specific error reason.
const char* topicName | The topic name for which to retrieve the alias. |
word
) for the specified topic name. Returns 0 if none is found.
word alias | The alias for which to retrieve the topic name. |
const char*
) or nullptr
if no name is found for the alias.
class UMqttClient {
public:
~UMqttClient() {}
virtual void MQTTClientConnectComplete(IMqttClient* const mqttClient,
bool isNewSession,
dword sessionExpiryInterval,
word receiveMaximum,
byte maxQoS,
byte retainAvailable,
dword maxPacketSize,
const char* clientId,
dword topicAliasMax,
const char* userPropertyName,
const char* userPropertyValue,
byte wildCardAvailable,
byte sharedSubscriptionAvailable,
dword serverKeepAlive) = 0;
virtual void MQTTClientConnectFail(IMqttClient* const mqttClient,
MQTTReasonCode reasonCode,
const char* reasonString) = 0;
virtual void MQTTClientDisconnect(IMqttClient* const mqttClient,
MQTTReasonCode reasonCode) = 0;
virtual void MQTTClientSubscribeComplete(IMqttClient* const mqttClient,
const char* topic,
const char* userPropertyName,
const char* userPropertyValue) = 0;
virtual void MQTTClientSubscribeFail(IMqttClient* const mqttClient,
const char* topic,
MQTTReasonCode reasonCode) = 0;
virtual void MQTTClientPublishRecv(IMqttClient* const mqttClient,
const char* topic,
const char* msg,
size_t msg_len,
word subscriptionIdentifier,
const char* userPropertyName,
const char* userPropertyValue) = 0;
virtual void MQTTClientUnsubscribeComplete(IMqttClient* const mqttClient,
const char* topic,
const char* userPropertyName,
const char* userPropertyValue) = 0;
virtual void MQTTClientUnsubscribeFail(IMqttClient* const mqttClient,
const char* topic,
MQTTReasonCode reasonCode) = 0;
virtual void MQTTClientPublishComplete(IMqttClient* const mqttClient,
const byte QoS,
const char* userPropertyName,
const char* userPropertyValue) = 0;
virtual void MQTTClientPublishFail(IMqttClient* const mqttClient,
MQTTReasonCode reasonCode) = 0;
virtual void MQTTClientPingComplete(IMqttClient* const mqttClient) = 0;
virtual void MQTTClientAuthenticate(IMqttClient* const mqttClient,
MQTTReasonCode reasonCode) = 0;
virtual void MQTTClientError(IMqttClient* const mqttClient,
MqttError reason) = 0;
};
This class is for receiving callbacks from the IMqttClient
. You must pass a subclass of UMqttClient
to an IMqttClient
as user in order
to handle events such as connection completion, disconnection, subscription success/failure, publish completion, incoming messages, errors, etc.
MQTTSendAuthData
.
enum MqttError {
Success = 0,
WrongPacketType,
Malformed,
BufferAllocationFailed,
NullBufferRecived,
MaxBinDataExceeded,
StringSizeExceeded,
VariableHeaderError,
PayloadError,
FlagSetButNoTopic,
FlagSetButNoPayload,
FlagSetButNoUserName,
FlagSetButNoPassword,
EmptyData,
IndexOutOfRange,
SubscriptionIdentifierMissing,
IncorrectValue,
NoConnectionEstablished,
UnspecifierError,
PacketTooLarge,
StringTooLarge,
OutputBufferToSmall,
InputClientIdIncorrect,
RetainNotSupportedByBroker,
TopicAliasNonExistant,
TopicAliasNotSupported,
TopicAliasUnavailable,
InvalidTopicName
};
MqttError
defines client-side error conditions during MQTT operations (e.g., Malformed
, IncorrectValue
).
enum MQTTReasonCode {
SUCCESS = 0x00,
NORMAL_DISCONNECTION = 0x00,
GRANTED_QOS0 = 0x00,
GRANTED_QOS1 = 0x01,
GRANTED_QOS2 = 0x02,
DISCONNECT_WITH_WILL_MESSAGE = 0x04,
NO_MATCHING_SUBSCRIBERS = 0x10,
NO_SUBSCRIPTION_EXISTED = 0x11,
CONTINUE_AUTHENTICATION = 0x18,
RE_AUTHENTICATE = 0x19,
UNSPECIFIED_ERROR = 0x80,
MALFORMED_PACKET = 0x81,
PROTOCOL_ERROR = 0x82,
IMPLEMENTATION_SPECIFIC_ERROR = 0x83,
UNSUPPORTED_PROTOCOL_VERSION = 0x84,
CLIENT_IDENTIFIER_NOT_VALID = 0x85,
BAD_USER_NAME_OR_PASSWORD = 0x86,
NOT_AUTHORIZED = 0x87,
SERVER_UNAVAILABLE = 0x88,
SERVER_BUSY = 0x89,
BANNED = 0x8A,
SERVER_SHUTTING_DOWN = 0x8B,
BAD_AUTHENTICATION_METHOD = 0x8C,
KEEP_ALIVE_TIMEOUT = 0x8D,
SESSION_TAKEN_OVER = 0x8E,
TOPIC_FILTER_INVALID = 0x8F,
TOPIC_NAME_INVALID = 0x90,
PACKET_IDENTIFIER_IN_USE = 0x91,
PACKET_IDENTIFIER_NOT_FOUND = 0x92,
RECEIVE_MAXIMUM_EXCEEDED = 0x93,
TOPIC_ALIAS_INVALID = 0x94,
PACKET_TOO_LARGE = 0x95,
MESSAGE_RATE_TOO_HIGH = 0x96,
QUOTA_EXCEEDED = 0x97,
ADMINISTRATIVE_ACTION = 0x98,
PAYLOAD_FORMAT_INVALID = 0x99,
RETAIN_NOT_SUPPORTED = 0x9A,
QOS_NOT_SUPPORTED = 0x9B,
USE_ANOTHER_SERVER = 0x9C,
SERVER_MOVED = 0x9D,
SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 0x9E,
CONNECTION_RATE_EXCEEDED = 0x9F,
MAXIMUM_CONNECT_TIME = 0xA0,
SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 0xA1,
WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 0xA2
};
MQTTReasonCode
enumerates the possible reason codes in MQTT for connection, disconnection, and other operations.
Reason Codes
.
enum MQTTAuthReasonCode {
ContinueAuthentication = 0x18,
Reauthenticate = 0x19
};
enum MQTTClientDisconnectReason {
NormalDisconnection = 0x00,
};
MQTTClientDisconnectReason
indicates the reason for disconnecting.
NormalDisconnection
(0x00) is used for a graceful disconnect.
Below is an example of connecting to a TLS broker on HiveMQ, showing how to generate a client ID (if needed), subscribe to multiple topics, and publish messages:
void TaskMqttTest::Start(UTask* user) {
// Note: This is an example to connect to a TLS broker from HiveMQ.
// Login data is anonymized here.
const char* username = "mqttUser";
byte* password = (byte*)"mqttPass";
word keepAlive = 60; // 60 seconds
word port = 8883;
// Example: we can create the client with the needed arguments:
client = IMqttClient::Create(instance->GetIIoMux(),
instance->GetTcpSocketProvider(),
instance->GetTlsSocketProvider(),
this,
instance->GetLog(),
dns->Create(instance->GetIIoMux()));
// If generating an ID, ensure 24 bytes are allocated for the 23-byte ID plus null terminator
char* generatedClientIdBuffer = (char*) malloc(24);
size_t bufferSize = 24; // For illustration
// Connect to the TLS broker at port 8883:
MqttError state = client->MQTTConnect("example.hivemq.cloud",
generatedClientIdBuffer, // outputClientId
bufferSize, // outputClientIdSize
port,
true, // TLS
username, // payloadUserName
password, // payloadPassword
strlen((char*)password), // payloadPasswordSize
nullptr, // inputClientId
keepAlive);
if (state) {
printf("ERROR");
}
}
void TaskMqttTest::MQTTClientConnectComplete(IMqttClient* const mqttClient, bool isNewSession,
dword sessionExpiryInterval, word receiveMaximum,
byte maxQoS, byte retainAvailable, dword maxPacketSize,
const char* clientId, dword topicAliasMax,
const char* userPropertyName, const char* userPropertyValue,
byte wildCardAvailable, byte sharedSubscriptionAvailable,
dword serverKeepAlive)
{
// For example, send a ping and subscribe to a wildcard topic:
client->MQTTPing();
// Subscribing with subscription identifier 12, topic "#", QoS "0"
client->MQTTSubscribe(12, "#", "0");
// Now publish a message to test/light1
byte* payload = (byte*)"innoClient MQTT5";
client->MQTTPublish("test/light1", 0, 0, payload, strlen((char*)payload));
}
void TaskMqttTest::MQTTClientDisconnect(IMqttClient* const mqttClient, MQTTReasonCode reasonCode)
{
printf("Disconnected with reason: %x", reasonCode);
}
void TaskMqttTest::MQTTClientConnectFail(IMqttClient* const mqttClient, MQTTReasonCode reasonCode, const char* reasonString)
{
printf("CONNECT FAILED");
}
void TaskMqttTest::MQTTClientPublishRecv(IMqttClient* const mqttClient, const char* topic, const char* msg, size_t msg_len, word subscriptionIdentifier,
const char* userPropertyName, const char* userPropertyValue)
{
printf("RECIVED NEW MESSAGE");
if (!strcmp(topic, "test/light2")) {
if (subscriptionIdentifier == 12) {
byte* payload = (byte*)"Next Message from innoClient";
client->MQTTPublish("test/light1", 0, 0, payload, strlen((char*)payload));
}
}
else {
printf("%s", msg);
}
}
void TaskMqttTest::MQTTClientPublishComplete(IMqttClient* const mqttClient, const byte QoS, const char* userPropertyName, const char* userPropertyValue)
{
printf("Publish completed.");
}
void TaskMqttTest::MQTTClientUnsubscribeComplete(IMqttClient* const mqttClient, const char* topic, const char* userPropertyName, const char* userPropertyValue)
{
printf("Unsubscribe TOPIC: %s", topic);
}
void TaskMqttTest::MQTTClientUnsubscribeFail(IMqttClient* const mqttClient, const char* topic, MQTTReasonCode reasonCode)
{
printf("Failed to Subscribe/Unsubscribe to: %s with ReasonCode:%x", topic, reasonCode);
}
void TaskMqttTest::MQTTClientPingComplete(IMqttClient* const mqttClient)
{
printf("Ping response received.");
}
void TaskMqttTest::MQTTClientSubscribeComplete(IMqttClient* const mqttClient, const char* topic, const char* userPropertyName, const char* userPropertyValue)
{
printf("Subscribed to TOPIC: %s", topic);
// If we subscribed to multiple topics: "test/light1, test/light2" with QoS "0,2"
// we can do further actions here.
if (!strcmp(topic, "test/light1, test/light2")) {
byte* payload = (byte*)"inno Client";
// Example publish with QoS 2
client->MQTTPublish("test/light1", 2, 0, payload, strlen((char*)payload));
}
}