diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/Binary.lby b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/Binary.lby new file mode 100644 index 0000000..52f8e9e --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/Binary.lby @@ -0,0 +1,20 @@ + + + + + Types.typ + Constants.var + IotMqtt.fun + + + + + + + + + + + + + \ No newline at end of file diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/Constants.var b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/Constants.var new file mode 100644 index 0000000..dce1395 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/Constants.var @@ -0,0 +1,43 @@ +(*Errors*) +VAR CONSTANT + IOTMQTT_ERR_NOT_FREE_HEAP : DINT := -10000; + IOTMQTT_ERR_NULL_HANDLE : DINT := -10001; + IOTMQTT_ERR_INVALID_HANDLE : DINT := -10002; + IOTMQTT_ERR_CA_CERTIFICATE : DINT := -10003; + IOTMQTT_ERR_CONNECTION_LOST : DINT := -10004; + IOTMQTT_ERR_CONNECTION_FAILED : DINT := -10005; + IOTMQTT_ERR_SUBSCRIBE : DINT := -10006; + IOTMQTT_ERR_FIFO_PUBLISH : DINT := -10007; + IOTMQTT_ERR_FIFO_SUBSCRIBE : DINT := -10008; + IOTMQTT_ERR_WRONG_PUBLISH_PAR : DINT := -10009; + IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR : DINT := -10010; + IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS : DINT := -10011; + IOTMQTT_ERR_WRONG_QUEUE_SIZE : DINT := -10012; + IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE : DINT := -10013; + IOTMQTT_ERR_CONN_REFUSED : DINT := -10014; + IOTMQTT_ERR_SENDING_TIMEDOUT : DINT := -10015; +END_VAR +(*Warnings*) +VAR CONSTANT + IOTMQTT_WRN_ALREADY_ALLOCATED : DINT := -20001; + IOTMQTT_WRN_ALREADY_FREED : DINT := -20002; + IOTMQTT_WRN_NO_MORE_MESSAGES : DINT := -20003; + IOTMQTT_WRN_FAILURE_SENDING : DINT := -20004; + IOTMQTT_WRN_FIFO_EMPTY : DINT := -20005; + IOTMQTT_WRN_CLIENT_DISABLED : DINT := -20006; + IOTMQTT_WRN_INVALID_DATA_RCVD : DINT := -20007; +END_VAR +(*OK*) +VAR CONSTANT + IOTMQTT_NO_ERR : DINT := 0; +END_VAR +(*Constants*) +VAR CONSTANT + MAX_SUBSCRIPTION_TOPICS : UINT := 50; + MAX_ENTRIES_RECEIVED_MESSAGES : UINT := 10; + MAX_ENTRIES_PUBLISH_MESSAGES : UINT := 500; + MAX_ENTRIES_SUBSCRIBE_OBJECTS : UINT := 50; + MAX_MESSAGE_TOKEN_TABLE : UINT := 1000; + MAX_PUBLISH_FUBS : UINT := 50; + MAX_SUBSCRIBE_FUBS : UINT := 50; +END_VAR diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/IotMqtt.fun b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/IotMqtt.fun new file mode 100644 index 0000000..dea6966 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/IotMqtt.fun @@ -0,0 +1,192 @@ + +{REDUND_ERROR} FUNCTION IotMqttConfig : INT (*Allows to configure library parameters. It only takes effect the first time it's called*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + ConfigParameters : REFERENCE TO IotMqttConfigParametersType; + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttClient + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + Connect : {REDUND_UNREPLICABLE} BOOL; (*If the FUB is enabled, attemps to connect with the remote MQTT broker*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Clears the current error*) + Parameters : {REDUND_UNREPLICABLE} IotMqttClientParType; (*Contains the client parameters*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and running*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttClientInfoType; (*Contains client information regarding the actual session*) + Connected : {REDUND_UNREPLICABLE} BOOL; (*TRUE if MQTT client is connected with the remote broker*) + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Send : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. Will send a new message each time is set high*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to data buffer*) + BufferLength : {REDUND_UNREPLICABLE} UDINT; (*Buffer length*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + END_VAR + VAR_OUTPUT + Busy : {REDUND_UNREPLICABLE} BOOL; (*Publishing*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Done : {REDUND_UNREPLICABLE} BOOL; (*Publish done*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Send : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _ErrorReset : {REDUND_UNREPLICABLE} BOOL; + _t0 : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Update : {REDUND_UNREPLICABLE} BOOL; (*Edfe sensitive. Will update the internal values for PvName, Mode, PublishMode and SamplingTime*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + PublishMode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; (*Which event or events will send the PV data?*) + SamplingTime : {REDUND_UNREPLICABLE} TIME; (*Sampling rate used for saving new values (used for time-based send mode). On a change, the new value is only applied on a rising edge of Update*) + Trigger : {REDUND_UNREPLICABLE} BOOL; (*Trigger (used for the recording mode that works with a trigger).*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*Working in serialization + sending*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Publish : {REDUND_UNREPLICABLE} IotMqttPublish; + _Serializer : {REDUND_UNREPLICABLE} UDINT; + _Processing : {REDUND_UNREPLICABLE} BOOL; + _prevPV : {REDUND_UNREPLICABLE} UDINT; + _trig : {REDUND_UNREPLICABLE} BOOL; + _addr : {REDUND_UNREPLICABLE} UDINT; + _datalen : {REDUND_UNREPLICABLE} UDINT; + _enable : {REDUND_UNREPLICABLE} BOOL; + _pvname : {REDUND_UNREPLICABLE} UDINT; + _publishmode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; + _mode : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; + _update : {REDUND_UNREPLICABLE} BOOL; + _samplingtime : {REDUND_UNREPLICABLE} TIME; + _t0 : {REDUND_UNREPLICABLE} TIME; + _pubCmd : {REDUND_UNREPLICABLE} BOOL; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB. Subscription will take place at enable of the FUB, if the associated IotMqttClient FUB is enabled and connected.*) + Read : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. When activaded it will deliver one message from the internal FIFO*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + SubscriptionQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + RecievedTopicSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the received topic buffer*) + QueueSize : {REDUND_UNREPLICABLE} USINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to memory area where the content of the read messages will be stored*) + BufferSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the memory area where the content of the read messages will be stored*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The read message from the FIFO has the "Retain" flag*) + ReceivedQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The read message from the FIFO has this QoS*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Subscribed : {REDUND_UNREPLICABLE} BOOL; (*Subscription completed succesfully*) + MessageRetrieved : {REDUND_UNREPLICABLE} BOOL; (*Read operation completed succesfully*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + NewDataValid : {REDUND_UNREPLICABLE} BOOL; (*Is TRUE if new data was received with the last FB call*) + DataSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the Buffer array used in bytes*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Enable : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _Internal : {REDUND_UNREPLICABLE} UDINT; + _FifoHandle : {REDUND_UNREPLICABLE} UDINT; + _Read : {REDUND_UNREPLICABLE} BOOL; + _Subscribing : {REDUND_UNREPLICABLE} BOOL; + _FifoLock : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + QueueSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The received message has the "Retain" flag*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + UpdateNotification : {REDUND_UNREPLICABLE} BOOL; (*registered PV contains new values. This is automatically reset after one cycle.*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Receive : {REDUND_UNREPLICABLE} IotMqttSubscribe; + _Parser : {REDUND_UNREPLICABLE} UDINT; + _RecvBuffer : {REDUND_UNREPLICABLE} UDINT; + _ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + _Step : {REDUND_UNREPLICABLE} USINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_ERROR} FUNCTION AzureGenerateDeviceCredentials : INT (*Given an AzureIoT Hub device connection string, and the "TimeToLive" parameter, will populate the needed parameters for connecting it*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + pConnectionString : UDINT; (*Pointer to string with the connection string*) + TimeToLive : USINT; (*Time in hours that the password will be valid*) + pParameters : UDINT; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + PublishTelemetryTopic : UDINT; (*Pointer to string to store the publish topic*) + SizeofPublishTelemetryTopic : UDINT; (*Size of PublishTelemetryTopic variable*) + SubscribeTelemetryTopic : UDINT; (*Pointer to string to store the subscribe topic*) + SizeofSubscribeTelemetryTopic : UDINT; (*Size of SubscribeTelemetryTopic variable*) + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK GoogleIotCredentials (*Get JWT token for MQTT connection*) + VAR_INPUT + Execute : {REDUND_UNREPLICABLE} BOOL; + pIotMqttGoogleIotParameters : REFERENCE TO IotMqttGoogleIotParametersType; + pJWT : {REDUND_UNREPLICABLE} UDINT; (*Pointer to string. It will be filled with JWT*) + SizeOfJWT : {REDUND_UNREPLICABLE} UDINT; (*Size of destination JWT string*) + pIotMqttClientParameters : REFERENCE TO IotMqttClientParType; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + END_VAR + VAR_OUTPUT + Error : {REDUND_UNREPLICABLE} BOOL; + Done : {REDUND_UNREPLICABLE} BOOL; + Busy : {REDUND_UNREPLICABLE} BOOL; + END_VAR + VAR + _Execute : {REDUND_UNREPLICABLE} BOOL; + _hTask : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/SG4/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/SG4/IotMqtt.br new file mode 100644 index 0000000..b20c881 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/SG4/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/SG4/IotMqtt.h b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/SG4/IotMqtt.h new file mode 100644 index 0000000..acff088 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/SG4/IotMqtt.h @@ -0,0 +1,474 @@ +/* Automation Studio generated header file */ +/* Do not edit ! */ +/* IotMqtt 3.10.0 */ + +#ifndef _IOTMQTT_ +#define _IOTMQTT_ +#ifdef __cplusplus +extern "C" +{ +#endif +#ifndef _IotMqtt_VERSION +#define _IotMqtt_VERSION 3.10.0 +#endif + +#include + +#ifndef _BUR_PUBLIC +#define _BUR_PUBLIC +#endif +#ifdef _SG3 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "AsETH.h" + #include "brsystem.h" + #include "AsArLog.h" + #include "AsIODiag.h" +#endif +#ifdef _SG4 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "AsETH.h" + #include "brsystem.h" + #include "AsArLog.h" + #include "AsIODiag.h" +#endif +#ifdef _SGC + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "AsETH.h" + #include "brsystem.h" + #include "AsArLog.h" + #include "AsIODiag.h" +#endif + + +/* Constants */ +#ifdef _REPLACE_CONST + #define IOTMQTT_ERR_NOT_FREE_HEAP (-10000) + #define IOTMQTT_ERR_NULL_HANDLE (-10001) + #define IOTMQTT_ERR_INVALID_HANDLE (-10002) + #define IOTMQTT_ERR_CA_CERTIFICATE (-10003) + #define IOTMQTT_ERR_CONNECTION_LOST (-10004) + #define IOTMQTT_ERR_CONNECTION_FAILED (-10005) + #define IOTMQTT_ERR_SUBSCRIBE (-10006) + #define IOTMQTT_ERR_FIFO_PUBLISH (-10007) + #define IOTMQTT_ERR_FIFO_SUBSCRIBE (-10008) + #define IOTMQTT_ERR_WRONG_PUBLISH_PAR (-10009) + #define IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR (-10010) + #define IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS (-10011) + #define IOTMQTT_ERR_WRONG_QUEUE_SIZE (-10012) + #define IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE (-10013) + #define IOTMQTT_ERR_CONN_REFUSED (-10014) + #define IOTMQTT_ERR_SENDING_TIMEDOUT (-10015) + #define IOTMQTT_WRN_ALREADY_ALLOCATED (-20001) + #define IOTMQTT_WRN_ALREADY_FREED (-20002) + #define IOTMQTT_WRN_NO_MORE_MESSAGES (-20003) + #define IOTMQTT_WRN_FAILURE_SENDING (-20004) + #define IOTMQTT_WRN_FIFO_EMPTY (-20005) + #define IOTMQTT_WRN_CLIENT_DISABLED (-20006) + #define IOTMQTT_WRN_INVALID_DATA_RCVD (-20007) + #define IOTMQTT_NO_ERR 0 + #define MAX_SUBSCRIPTION_TOPICS 50U + #define MAX_ENTRIES_RECEIVED_MESSAGES 10U + #define MAX_ENTRIES_PUBLISH_MESSAGES 500U + #define MAX_ENTRIES_SUBSCRIBE_OBJECTS 50U + #define MAX_MESSAGE_TOKEN_TABLE 1000U + #define MAX_PUBLISH_FUBS 50U + #define MAX_SUBSCRIBE_FUBS 50U +#else + _GLOBAL_CONST signed long IOTMQTT_ERR_NOT_FREE_HEAP; + _GLOBAL_CONST signed long IOTMQTT_ERR_NULL_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_INVALID_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CA_CERTIFICATE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_LOST; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_FAILED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_PUBLISH; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_PUBLISH_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_QUEUE_SIZE; + _GLOBAL_CONST signed long IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONN_REFUSED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SENDING_TIMEDOUT; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_ALLOCATED; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_FREED; + _GLOBAL_CONST signed long IOTMQTT_WRN_NO_MORE_MESSAGES; + _GLOBAL_CONST signed long IOTMQTT_WRN_FAILURE_SENDING; + _GLOBAL_CONST signed long IOTMQTT_WRN_FIFO_EMPTY; + _GLOBAL_CONST signed long IOTMQTT_WRN_CLIENT_DISABLED; + _GLOBAL_CONST signed long IOTMQTT_WRN_INVALID_DATA_RCVD; + _GLOBAL_CONST signed long IOTMQTT_NO_ERR; + _GLOBAL_CONST unsigned short MAX_SUBSCRIPTION_TOPICS; + _GLOBAL_CONST unsigned short MAX_ENTRIES_RECEIVED_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_PUBLISH_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_SUBSCRIBE_OBJECTS; + _GLOBAL_CONST unsigned short MAX_MESSAGE_TOKEN_TABLE; + _GLOBAL_CONST unsigned short MAX_PUBLISH_FUBS; + _GLOBAL_CONST unsigned short MAX_SUBSCRIBE_FUBS; +#endif + + + + +/* Datatypes and datatypes of function blocks */ +typedef enum IotMqttConnTypeEnum +{ IotMqtt_TCP, + IotMqtt_WS +} IotMqttConnTypeEnum; + +typedef enum IotMqttQosEnum +{ IotMqtt_QoS0 = 0, + IotMqtt_QoS1 = 1, + IotMqtt_QoS2 = 2 +} IotMqttQosEnum; + +typedef enum IotMqttPublishModeEnum +{ IOTMQTT_PUB_MODE_TIME, + IOTMQTT_PUB_MODE_TRIGGER, + IOTMQTT_PUB_MODE_VALUE, + IOTMQTT_PUB_MODE_TIME_TRIGGER, + IOTMQTT_PUB_MODE_TIME_VALUE, + IOTMQTT_PUB_MODE_TRIGGER_VALUE, + IOTMQTT_PUB_MODE_TIME_TRG_VALUE +} IotMqttPublishModeEnum; + +typedef enum IotMqttLogLevelEnum +{ IOTMQTT_LOG_LEVEL_ERROR, + IOTMQTT_LOG_LEVEL_PROTOCOL, + IOTMQTT_LOG_LEVEL_MAXIMUM +} IotMqttLogLevelEnum; + +typedef enum IotMqttDataFormatEnum +{ IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON +} IotMqttDataFormatEnum; + +typedef enum IotMqttConnectionStateEnum +{ IOTMQTT_DISABLED, + IOTMQTT_DISCONNECTED, + IOTMQTT_DISCONNECTING, + IOTMQTT_CONNECTED, + IOTMQTT_CONNECTING, + IOTMQTT_CONNECTION_LOST, + IOTMQTT_CONNECTION_ERROR +} IotMqttConnectionStateEnum; + +typedef enum IotMqttGoogleIotJwtAlgorithmEnum +{ IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 +} IotMqttGoogleIotJwtAlgorithmEnum; + +typedef struct IotMqttPayloadType +{ unsigned long pData; + unsigned long Len; +} IotMqttPayloadType; + +typedef struct IotMqttSubscribeInfoType +{ unsigned long NumberOfLostMessages; + unsigned long MessagesInQueue; + unsigned long AvailableMessageSlots; + unsigned long TotalReceivedMessages; +} IotMqttSubscribeInfoType; + +typedef struct IotMqttPublishInfoType +{ unsigned long MessagesPublished; + unsigned long DeliveriesCompleted; + unsigned long PublishErrorCounter; +} IotMqttPublishInfoType; + +typedef struct IotMqttClientParLastWillType +{ plcbit UseLastWill; + unsigned long Topic; + unsigned long Buffer; + unsigned long BufferLength; + enum IotMqttQosEnum QoS; + plcbit Retain; + struct IotMqttPayloadType Payload; +} IotMqttClientParLastWillType; + +typedef struct IotMqttClientParTLSType +{ plcbit UseTLS; + unsigned long CA; + unsigned long Cert; + unsigned long PrivateKey; + unsigned long PrivateKeyPassword; + unsigned long EnabledCipherSuites; + plcbit EnableServerCertAuth; +} IotMqttClientParTLSType; + +typedef struct IotMqttClientParType +{ plcstring ServerUri[256]; + unsigned short Port; + plcstring ClientID[256]; + plcstring UserName[256]; + plcstring Password[256]; + plctime KeepAliveInterval; + struct IotMqttClientParLastWillType LastWill; + plctime ConnectTimeout; + unsigned short MaxInFlight; + plctime MinRetryInterval; + plctime MaxRetryInterval; + struct IotMqttClientParTLSType TLS; + plcbit PersistentData; + plcbit AutomaticReconnect; + enum IotMqttConnTypeEnum ConnectionType; + plcbit CleanSession; + plcbit OfflinePublish; + unsigned short OfflinePublishBuffer; +} IotMqttClientParType; + +typedef struct IotMqttClientInfoType +{ enum IotMqttConnectionStateEnum ConnectionState; + unsigned long NumberActivePublishersFubs; + unsigned long NumberActiveSubscribersFubs; + unsigned long PublishMessageCount; + unsigned long SubscribeMessageCount; + unsigned long PendingMessagesCount; +} IotMqttClientInfoType; + +typedef struct IotMqttReceivedMessageType +{ unsigned long Topic; + unsigned short TopicLen; + unsigned long Buffer; + unsigned long BufferLen; + unsigned char QoS; + plcbit Retained; +} IotMqttReceivedMessageType; + +typedef struct IoTMqttComIdentType +{ unsigned long Internal; + unsigned long pThreadHandle; + unsigned long pThreadAttr; + unsigned long inst; +} IoTMqttComIdentType; + +typedef struct IotMqttConfigParametersType +{ enum IotMqttLogLevelEnum LogLevel; + plcbit UseLogger; + plcstring LoggerName[9]; + unsigned long LoggerSize; + plcbit UseFile; + plcstring LogFileName[81]; + plcstring LogFileDevice[81]; + plcbit AppendTimestamp; + plcbit OverwritteLogs; + plcstring PersistenceFileDevice[81]; +} IotMqttConfigParametersType; + +typedef struct IotMqttGoogleIotParametersType +{ plcstring ProjectID[81]; + plcstring Region[81]; + plcstring RegistryID[81]; + plcstring DeviceID[81]; + plctime ExpirationPeriod; + enum IotMqttGoogleIotJwtAlgorithmEnum Algorithm; +} IotMqttGoogleIotParametersType; + +typedef struct IotMqttClient +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + struct IotMqttClientParType Parameters; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttClientInfoType Info; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Connect; + plcbit ErrorReset; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Error; + plcbit Connected; +} IotMqttClient_typ; + +typedef struct IotMqttPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + plctime SendTimeout; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long Buffer; + unsigned long BufferLength; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + unsigned long _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Send; + plcbit Retained; + /* VAR_OUTPUT (digital) */ + plcbit Busy; + plcbit Active; + plcbit Done; + plcbit Error; + /* VAR (digital) */ + plcbit _Send; + plcbit _Active; + plcbit _ErrorReset; +} IotMqttPublish_typ; + +typedef struct IotMqttRegParPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum QoS; + plctime SendTimeout; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + enum IotMqttPublishModeEnum PublishMode; + plctime SamplingTime; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + struct IotMqttPublish _Publish; + unsigned long _Serializer; + unsigned long _prevPV; + unsigned long _addr; + unsigned long _datalen; + unsigned long _pvname; + enum IotMqttPublishModeEnum _publishmode; + enum IotMqttDataFormatEnum _mode; + plctime _samplingtime; + plctime _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Update; + plcbit Retained; + plcbit Trigger; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Busy; + plcbit Error; + /* VAR (digital) */ + plcbit _Processing; + plcbit _trig; + plcbit _enable; + plcbit _update; + plcbit _pubCmd; +} IotMqttRegParPublish_typ; + +typedef struct IotMqttSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum SubscriptionQoS; + unsigned long RecievedTopic; + unsigned long RecievedTopicSize; + unsigned char QueueSize; + unsigned long Buffer; + unsigned long BufferSize; + /* VAR_OUTPUT (analog) */ + enum IotMqttQosEnum ReceivedQoS; + signed long StatusID; + unsigned long DataSize; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + unsigned long _Internal; + unsigned long _FifoHandle; + unsigned long _FifoLock; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Read; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Subscribed; + plcbit MessageRetrieved; + plcbit Error; + plcbit Busy; + plcbit NewDataValid; + /* VAR (digital) */ + plcbit _Enable; + plcbit _Active; + plcbit _Read; + plcbit _Subscribing; +} IotMqttSubscribe_typ; + +typedef struct IotMqttRegParSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long RecievedTopic; + unsigned long QueueSize; + unsigned long ReceiveBufferSize; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + struct IotMqttSubscribe _Receive; + unsigned long _Parser; + unsigned long _RecvBuffer; + unsigned long _ReceiveBufferSize; + unsigned char _Step; + /* VAR_INPUT (digital) */ + plcbit Enable; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Busy; + plcbit Error; + plcbit UpdateNotification; +} IotMqttRegParSubscribe_typ; + +typedef struct GoogleIotCredentials +{ + /* VAR_INPUT (analog) */ + struct IotMqttGoogleIotParametersType* pIotMqttGoogleIotParameters; + unsigned long pJWT; + unsigned long SizeOfJWT; + struct IotMqttClientParType* pIotMqttClientParameters; + /* VAR (analog) */ + unsigned long _hTask; + /* VAR_INPUT (digital) */ + plcbit Execute; + /* VAR_OUTPUT (digital) */ + plcbit Error; + plcbit Done; + plcbit Busy; + /* VAR (digital) */ + plcbit _Execute; +} GoogleIotCredentials_typ; + + + +/* Prototyping of functions and function blocks */ +_BUR_PUBLIC void IotMqttClient(struct IotMqttClient* inst); +_BUR_PUBLIC void IotMqttPublish(struct IotMqttPublish* inst); +_BUR_PUBLIC void IotMqttRegParPublish(struct IotMqttRegParPublish* inst); +_BUR_PUBLIC void IotMqttSubscribe(struct IotMqttSubscribe* inst); +_BUR_PUBLIC void IotMqttRegParSubscribe(struct IotMqttRegParSubscribe* inst); +_BUR_PUBLIC void GoogleIotCredentials(struct GoogleIotCredentials* inst); +_BUR_PUBLIC signed short IotMqttConfig(struct IotMqttConfigParametersType** ConfigParameters); +_BUR_PUBLIC signed short AzureGenerateDeviceCredentials(unsigned long pConnectionString, unsigned char TimeToLive, unsigned long pParameters, unsigned long PublishTelemetryTopic, unsigned long SizeofPublishTelemetryTopic, unsigned long SubscribeTelemetryTopic, unsigned long SizeofSubscribeTelemetryTopic); + + +#ifdef __cplusplus +}; +#endif +#endif /* _IOTMQTT_ */ + diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/SG4/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/SG4/libIotMqtt.a new file mode 100644 index 0000000..02e63eb Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/SG4/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/Types.typ b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/Types.typ new file mode 100644 index 0000000..42ac63c --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V3.10.0/Types.typ @@ -0,0 +1,159 @@ + +TYPE + IotMqttConnTypeEnum : + ( + IotMqtt_TCP, (*Use standard TCP connection*) + IotMqtt_WS (*Use connection over websockets*) + ); + IotMqttQosEnum : + ( (*The quality of service (QoS) assigned to the message. +*) + IotMqtt_QoS0 := 0, (*Fire and forget - the message may not be delivered*) + IotMqtt_QoS1 := 1, (*At least once - the message will be delivered, but may be delivered more than once in some circumstances*) + IotMqtt_QoS2 := 2 (*Once and one only - the message will be delivered exactly once.*) + ); + IotMqttPublishModeEnum : + ( + IOTMQTT_PUB_MODE_TIME, (*New data is published on a time basis. *) + IOTMQTT_PUB_MODE_TRIGGER, (*New data is published after a trigger. *) + IOTMQTT_PUB_MODE_VALUE, (*New data from the PVs is published after the value of the PV is changed. *) + IOTMQTT_PUB_MODE_TIME_TRIGGER, (*New data is published at a certain time or after a trigger. *) + IOTMQTT_PUB_MODE_TIME_VALUE, (*New data is published at a certain time or after the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TRIGGER_VALUE, (*New data is published after a trigger or the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TIME_TRG_VALUE (*New data is published at a certain time, after the value of the registered PV changes or after a trigger. *) + ); + IotMqttLogLevelEnum : + ( + IOTMQTT_LOG_LEVEL_ERROR, (*Just errors are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_PROTOCOL, (*MQTT protocol operations are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_MAXIMUM (*Diagnosis messages are written to the log file or logger*) + ); + IotMqttDataFormatEnum : + ( + IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON + ); + IotMqttConnectionStateEnum : + ( + IOTMQTT_DISABLED, (*Client FUB is disabled*) + IOTMQTT_DISCONNECTED, (*Client FUB is enabled and disconnected*) + IOTMQTT_DISCONNECTING, (*Client FUB is enabled and disconnecting*) + IOTMQTT_CONNECTED, (*Client FUB is enabled and connected*) + IOTMQTT_CONNECTING, (*Client FUB is enabled and connecting*) + IOTMQTT_CONNECTION_LOST, (*Client FUB is enabled and lost the connection*) + IOTMQTT_CONNECTION_ERROR (*Client FUB is enabled and can't connect*) + ); + IotMqttPayloadType : STRUCT + pData : UDINT; (*Pointer to data buffer*) + Len : UDINT; (*Length of data buffer*) + END_STRUCT; + IotMqttSubscribeInfoType : STRUCT + NumberOfLostMessages : UDINT; (*Number of discarded messages because fifo was full*) + MessagesInQueue : UDINT; (*Number of waiting messages in the fifo*) + AvailableMessageSlots : UDINT; (*Number of available message slots in the fifo*) + TotalReceivedMessages : UDINT; (*Total number of received messages (including discarded messages)*) + END_STRUCT; + IotMqttPublishInfoType : STRUCT + MessagesPublished : UDINT; (*Number of sent messages*) + DeliveriesCompleted : UDINT; (*Number of acknowledged messages (delivery confirmed). Only used when QoS > 0*) + PublishErrorCounter : UDINT; (*Number of errors publishing*) + END_STRUCT; + IotMqttClientParType : STRUCT + ServerUri : STRING[255]; (*String containing broker's URI*) + Port : UINT := 1883; (*TCP port number used to connect to MQTT broker*) + ClientID : STRING[255]; (*String containing ClientID. Must be unique inside the broker*) + UserName : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the user name parameter*) + Password : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the password parameter*) + KeepAliveInterval : TIME := T#30s; (*The "keep alive" interval, defines the maximum time +that should pass without communication between the client and the server +The client will ensure that at least one message travels across the +network within each keep alive period. In the absence of a data-related +message during the time period, the client sends a very small MQTT +"ping" message, which the server will acknowledge. The keep alive +interval enables the client to detect when the server is no longer +available without having to wait for the long TCP/IP timeout. +Set to 0 if you do not want any keep alive processing.*) + LastWill : IotMqttClientParLastWillType; (*LastWill is enabled when the Topic Pointer is set*) + ConnectTimeout : TIME; (*The time interval to allow a connect to complete*) + MaxInFlight : UINT; (*This controls how many messages can be in-flight simultaneously.*) + MinRetryInterval : TIME; (*Minimum retry interval . Doubled on each failed retry*) + MaxRetryInterval : TIME; (*Maximum retry interval . The doubling stops here on failed retries.*) + TLS : IotMqttClientParTLSType; (*TLS parameters*) + PersistentData : BOOL; (*Enables persistentData on QOS > 0 items*) + AutomaticReconnect : BOOL := TRUE; (*Reconnect automatically in the case of a connection being lost*) + ConnectionType : IotMqttConnTypeEnum := IotMqtt_TCP; (*Determines if the connection will use standard TCP or WebSockets*) + CleanSession : BOOL; (*When cleansession is true, the state information is discarded at connect and disconnect. Setting cleansession to false keeps the state information*) + OfflinePublish : {REDUND_UNREPLICABLE} BOOL := FALSE; (*Whether to allow messages to be sent when the client is not connected.*) + OfflinePublishBuffer : UINT := 100; (*The maximum number of messages allowed to be buffered while not connected.*) + END_STRUCT; + IotMqttClientParTLSType : STRUCT + UseTLS : BOOL; (*Set to TRUE if TLS encryption is needed*) + CA : UDINT; (*Pointer to string. Name of the ca certificate stored in the CertificateStore*) + Cert : UDINT; (*Pointer to string. Name of the client certificate file stored in the CertificateStore*) + PrivateKey : UDINT; (*Pointer to string. Name of the private key file stored in the CertificateStore*) + PrivateKeyPassword : UDINT; (*Pointer to string. The password to load the client's privateKey if encrypted*) + EnabledCipherSuites : UDINT; (*Pointer to String.The list of cipher suites that the client will present to the server during the SSL handshake. For a +full explanation of the cipher list format, please see the OpenSSL on-line documentation: +http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT +If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding +those offering no encryption- will be considered. +This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).*) + EnableServerCertAuth : BOOL; (*True/False option to enable verification of the server certificate*) + END_STRUCT; + IotMqttClientParLastWillType : STRUCT + UseLastWill : BOOL; (*Makes use of last will and testament feature*) + Topic : UDINT; (*Pointer to NULL terminated string containing topic of the message*) + Buffer : UDINT; (*Pointer to NULL terminated string with the content of the message*) + BufferLength : UDINT; (*Bufferlenght to send*) + QoS : IotMqttQosEnum; (*QoS parameter (0 - 2)*) + Retain : BOOL; (*Is the message of type retain?*) + Payload : IotMqttPayloadType; (*Content payload, to be used (instead of Buffer) when sending binary data*) + END_STRUCT; + IotMqttClientInfoType : STRUCT + ConnectionState : IotMqttConnectionStateEnum; (*Unable to find host , Connecting , Connected , Connection Lost , Retrying *) + NumberActivePublishersFubs : UDINT; (*Number of active Publishers FUBs attached to this client*) + NumberActiveSubscribersFubs : UDINT; (*Number of active Subscribers FUBs attached to this client*) + PublishMessageCount : UDINT; (*Total number of messages published by this client since enabled*) + SubscribeMessageCount : UDINT; (*Total number of messages received by this client since enabled*) + PendingMessagesCount : UDINT; (*Total number of messages pendinf of delivery*) + END_STRUCT; + IotMqttReceivedMessageType : STRUCT + Topic : UDINT; (*Pointer to the topic of the message*) + TopicLen : UINT; (*Length of the topic*) + Buffer : UDINT; (*Pointer to the buffer with the content of the message*) + BufferLen : UDINT; (*Length of the message buffer*) + QoS : USINT; (*QoS parameter (0 - 2)*) + Retained : BOOL; (*Is the message of type retain?*) + END_STRUCT; + IoTMqttComIdentType : STRUCT + Internal : UDINT; + pThreadHandle : UDINT; + pThreadAttr : UDINT; + inst : UDINT; + END_STRUCT; + IotMqttConfigParametersType : STRUCT + LogLevel : IotMqttLogLevelEnum := IOTMQTT_LOG_LEVEL_ERROR; (*Log level*) + UseLogger : BOOL := 0; (*Use logger*) + LoggerName : STRING[8] := 'IotMqtt'; (*String containing the logger name. Only used if UseLogger is set*) + LoggerSize : UDINT := 2000000; (*Size of the logger in bytes*) + UseFile : BOOL := 1; (*Use file to output the log results*) + LogFileName : STRING[80] := 'IotMqttLog.txt'; (*String containing the file name. Only used if UseFile is set*) + LogFileDevice : STRING[80] := ''; (*String containing the filedevice name. Only used if UseFile is set*) + AppendTimestamp : BOOL := FALSE; (*A timestamp will be added to the filename so that it generates unique filenames. If disabled and the file already exists, it will be overwritten*) + OverwritteLogs : BOOL := TRUE; (*If set, it will delete previous logs if the name matches and no timestamp is added*) + PersistenceFileDevice : STRING[80] := 'IOTMQTT'; (*String containing the FileDevice for persistence files*) + END_STRUCT; + IotMqttGoogleIotJwtAlgorithmEnum : + ( + IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 + ); + IotMqttGoogleIotParametersType : STRUCT + ProjectID : STRING[80]; + Region : STRING[80]; + RegistryID : STRING[80]; + DeviceID : STRING[80]; + ExpirationPeriod : TIME; (*Token expiration period*) + Algorithm : IotMqttGoogleIotJwtAlgorithmEnum; + END_STRUCT; +END_TYPE diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/Binary.lby b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/Binary.lby new file mode 100644 index 0000000..248c31a --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/Binary.lby @@ -0,0 +1,21 @@ + + + + + Types.typ + Constants.var + IotMqtt.fun + + + + + + + + + + + + + + \ No newline at end of file diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/Constants.var b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/Constants.var new file mode 100644 index 0000000..dce1395 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/Constants.var @@ -0,0 +1,43 @@ +(*Errors*) +VAR CONSTANT + IOTMQTT_ERR_NOT_FREE_HEAP : DINT := -10000; + IOTMQTT_ERR_NULL_HANDLE : DINT := -10001; + IOTMQTT_ERR_INVALID_HANDLE : DINT := -10002; + IOTMQTT_ERR_CA_CERTIFICATE : DINT := -10003; + IOTMQTT_ERR_CONNECTION_LOST : DINT := -10004; + IOTMQTT_ERR_CONNECTION_FAILED : DINT := -10005; + IOTMQTT_ERR_SUBSCRIBE : DINT := -10006; + IOTMQTT_ERR_FIFO_PUBLISH : DINT := -10007; + IOTMQTT_ERR_FIFO_SUBSCRIBE : DINT := -10008; + IOTMQTT_ERR_WRONG_PUBLISH_PAR : DINT := -10009; + IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR : DINT := -10010; + IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS : DINT := -10011; + IOTMQTT_ERR_WRONG_QUEUE_SIZE : DINT := -10012; + IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE : DINT := -10013; + IOTMQTT_ERR_CONN_REFUSED : DINT := -10014; + IOTMQTT_ERR_SENDING_TIMEDOUT : DINT := -10015; +END_VAR +(*Warnings*) +VAR CONSTANT + IOTMQTT_WRN_ALREADY_ALLOCATED : DINT := -20001; + IOTMQTT_WRN_ALREADY_FREED : DINT := -20002; + IOTMQTT_WRN_NO_MORE_MESSAGES : DINT := -20003; + IOTMQTT_WRN_FAILURE_SENDING : DINT := -20004; + IOTMQTT_WRN_FIFO_EMPTY : DINT := -20005; + IOTMQTT_WRN_CLIENT_DISABLED : DINT := -20006; + IOTMQTT_WRN_INVALID_DATA_RCVD : DINT := -20007; +END_VAR +(*OK*) +VAR CONSTANT + IOTMQTT_NO_ERR : DINT := 0; +END_VAR +(*Constants*) +VAR CONSTANT + MAX_SUBSCRIPTION_TOPICS : UINT := 50; + MAX_ENTRIES_RECEIVED_MESSAGES : UINT := 10; + MAX_ENTRIES_PUBLISH_MESSAGES : UINT := 500; + MAX_ENTRIES_SUBSCRIBE_OBJECTS : UINT := 50; + MAX_MESSAGE_TOKEN_TABLE : UINT := 1000; + MAX_PUBLISH_FUBS : UINT := 50; + MAX_SUBSCRIBE_FUBS : UINT := 50; +END_VAR diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/IotMqtt.fun b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/IotMqtt.fun new file mode 100644 index 0000000..dea6966 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/IotMqtt.fun @@ -0,0 +1,192 @@ + +{REDUND_ERROR} FUNCTION IotMqttConfig : INT (*Allows to configure library parameters. It only takes effect the first time it's called*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + ConfigParameters : REFERENCE TO IotMqttConfigParametersType; + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttClient + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + Connect : {REDUND_UNREPLICABLE} BOOL; (*If the FUB is enabled, attemps to connect with the remote MQTT broker*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Clears the current error*) + Parameters : {REDUND_UNREPLICABLE} IotMqttClientParType; (*Contains the client parameters*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and running*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttClientInfoType; (*Contains client information regarding the actual session*) + Connected : {REDUND_UNREPLICABLE} BOOL; (*TRUE if MQTT client is connected with the remote broker*) + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Send : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. Will send a new message each time is set high*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to data buffer*) + BufferLength : {REDUND_UNREPLICABLE} UDINT; (*Buffer length*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + END_VAR + VAR_OUTPUT + Busy : {REDUND_UNREPLICABLE} BOOL; (*Publishing*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Done : {REDUND_UNREPLICABLE} BOOL; (*Publish done*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Send : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _ErrorReset : {REDUND_UNREPLICABLE} BOOL; + _t0 : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Update : {REDUND_UNREPLICABLE} BOOL; (*Edfe sensitive. Will update the internal values for PvName, Mode, PublishMode and SamplingTime*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + PublishMode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; (*Which event or events will send the PV data?*) + SamplingTime : {REDUND_UNREPLICABLE} TIME; (*Sampling rate used for saving new values (used for time-based send mode). On a change, the new value is only applied on a rising edge of Update*) + Trigger : {REDUND_UNREPLICABLE} BOOL; (*Trigger (used for the recording mode that works with a trigger).*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*Working in serialization + sending*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Publish : {REDUND_UNREPLICABLE} IotMqttPublish; + _Serializer : {REDUND_UNREPLICABLE} UDINT; + _Processing : {REDUND_UNREPLICABLE} BOOL; + _prevPV : {REDUND_UNREPLICABLE} UDINT; + _trig : {REDUND_UNREPLICABLE} BOOL; + _addr : {REDUND_UNREPLICABLE} UDINT; + _datalen : {REDUND_UNREPLICABLE} UDINT; + _enable : {REDUND_UNREPLICABLE} BOOL; + _pvname : {REDUND_UNREPLICABLE} UDINT; + _publishmode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; + _mode : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; + _update : {REDUND_UNREPLICABLE} BOOL; + _samplingtime : {REDUND_UNREPLICABLE} TIME; + _t0 : {REDUND_UNREPLICABLE} TIME; + _pubCmd : {REDUND_UNREPLICABLE} BOOL; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB. Subscription will take place at enable of the FUB, if the associated IotMqttClient FUB is enabled and connected.*) + Read : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. When activaded it will deliver one message from the internal FIFO*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + SubscriptionQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + RecievedTopicSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the received topic buffer*) + QueueSize : {REDUND_UNREPLICABLE} USINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to memory area where the content of the read messages will be stored*) + BufferSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the memory area where the content of the read messages will be stored*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The read message from the FIFO has the "Retain" flag*) + ReceivedQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The read message from the FIFO has this QoS*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Subscribed : {REDUND_UNREPLICABLE} BOOL; (*Subscription completed succesfully*) + MessageRetrieved : {REDUND_UNREPLICABLE} BOOL; (*Read operation completed succesfully*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + NewDataValid : {REDUND_UNREPLICABLE} BOOL; (*Is TRUE if new data was received with the last FB call*) + DataSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the Buffer array used in bytes*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Enable : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _Internal : {REDUND_UNREPLICABLE} UDINT; + _FifoHandle : {REDUND_UNREPLICABLE} UDINT; + _Read : {REDUND_UNREPLICABLE} BOOL; + _Subscribing : {REDUND_UNREPLICABLE} BOOL; + _FifoLock : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + QueueSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The received message has the "Retain" flag*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + UpdateNotification : {REDUND_UNREPLICABLE} BOOL; (*registered PV contains new values. This is automatically reset after one cycle.*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Receive : {REDUND_UNREPLICABLE} IotMqttSubscribe; + _Parser : {REDUND_UNREPLICABLE} UDINT; + _RecvBuffer : {REDUND_UNREPLICABLE} UDINT; + _ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + _Step : {REDUND_UNREPLICABLE} USINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_ERROR} FUNCTION AzureGenerateDeviceCredentials : INT (*Given an AzureIoT Hub device connection string, and the "TimeToLive" parameter, will populate the needed parameters for connecting it*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + pConnectionString : UDINT; (*Pointer to string with the connection string*) + TimeToLive : USINT; (*Time in hours that the password will be valid*) + pParameters : UDINT; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + PublishTelemetryTopic : UDINT; (*Pointer to string to store the publish topic*) + SizeofPublishTelemetryTopic : UDINT; (*Size of PublishTelemetryTopic variable*) + SubscribeTelemetryTopic : UDINT; (*Pointer to string to store the subscribe topic*) + SizeofSubscribeTelemetryTopic : UDINT; (*Size of SubscribeTelemetryTopic variable*) + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK GoogleIotCredentials (*Get JWT token for MQTT connection*) + VAR_INPUT + Execute : {REDUND_UNREPLICABLE} BOOL; + pIotMqttGoogleIotParameters : REFERENCE TO IotMqttGoogleIotParametersType; + pJWT : {REDUND_UNREPLICABLE} UDINT; (*Pointer to string. It will be filled with JWT*) + SizeOfJWT : {REDUND_UNREPLICABLE} UDINT; (*Size of destination JWT string*) + pIotMqttClientParameters : REFERENCE TO IotMqttClientParType; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + END_VAR + VAR_OUTPUT + Error : {REDUND_UNREPLICABLE} BOOL; + Done : {REDUND_UNREPLICABLE} BOOL; + Busy : {REDUND_UNREPLICABLE} BOOL; + END_VAR + VAR + _Execute : {REDUND_UNREPLICABLE} BOOL; + _hTask : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/SG4/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/SG4/IotMqtt.br new file mode 100644 index 0000000..bbbab21 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/SG4/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/SG4/IotMqtt.h b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/SG4/IotMqtt.h new file mode 100644 index 0000000..19d0870 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/SG4/IotMqtt.h @@ -0,0 +1,477 @@ +/* Automation Studio generated header file */ +/* Do not edit ! */ +/* IotMqtt 4.26.0 */ + +#ifndef _IOTMQTT_ +#define _IOTMQTT_ +#ifdef __cplusplus +extern "C" +{ +#endif +#ifndef _IotMqtt_VERSION +#define _IotMqtt_VERSION 4.26.0 +#endif + +#include + +#ifndef _BUR_PUBLIC +#define _BUR_PUBLIC +#endif +#ifdef _SG3 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "brsystem.h" + #include "AsIODiag.h" +#endif +#ifdef _SG4 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "brsystem.h" + #include "AsIODiag.h" +#endif +#ifdef _SGC + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "brsystem.h" + #include "AsIODiag.h" +#endif + + +/* Constants */ +#ifdef _REPLACE_CONST + #define IOTMQTT_ERR_NOT_FREE_HEAP (-10000) + #define IOTMQTT_ERR_NULL_HANDLE (-10001) + #define IOTMQTT_ERR_INVALID_HANDLE (-10002) + #define IOTMQTT_ERR_CA_CERTIFICATE (-10003) + #define IOTMQTT_ERR_CONNECTION_LOST (-10004) + #define IOTMQTT_ERR_CONNECTION_FAILED (-10005) + #define IOTMQTT_ERR_SUBSCRIBE (-10006) + #define IOTMQTT_ERR_FIFO_PUBLISH (-10007) + #define IOTMQTT_ERR_FIFO_SUBSCRIBE (-10008) + #define IOTMQTT_ERR_WRONG_PUBLISH_PAR (-10009) + #define IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR (-10010) + #define IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS (-10011) + #define IOTMQTT_ERR_WRONG_QUEUE_SIZE (-10012) + #define IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE (-10013) + #define IOTMQTT_ERR_CONN_REFUSED (-10014) + #define IOTMQTT_ERR_SENDING_TIMEDOUT (-10015) + #define IOTMQTT_WRN_ALREADY_ALLOCATED (-20001) + #define IOTMQTT_WRN_ALREADY_FREED (-20002) + #define IOTMQTT_WRN_NO_MORE_MESSAGES (-20003) + #define IOTMQTT_WRN_FAILURE_SENDING (-20004) + #define IOTMQTT_WRN_FIFO_EMPTY (-20005) + #define IOTMQTT_WRN_CLIENT_DISABLED (-20006) + #define IOTMQTT_WRN_INVALID_DATA_RCVD (-20007) + #define IOTMQTT_NO_ERR 0 + #define MAX_SUBSCRIPTION_TOPICS 50U + #define MAX_ENTRIES_RECEIVED_MESSAGES 10U + #define MAX_ENTRIES_PUBLISH_MESSAGES 500U + #define MAX_ENTRIES_SUBSCRIBE_OBJECTS 50U + #define MAX_MESSAGE_TOKEN_TABLE 1000U + #define MAX_PUBLISH_FUBS 50U + #define MAX_SUBSCRIBE_FUBS 50U +#else + _GLOBAL_CONST signed long IOTMQTT_ERR_NOT_FREE_HEAP; + _GLOBAL_CONST signed long IOTMQTT_ERR_NULL_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_INVALID_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CA_CERTIFICATE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_LOST; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_FAILED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_PUBLISH; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_PUBLISH_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_QUEUE_SIZE; + _GLOBAL_CONST signed long IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONN_REFUSED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SENDING_TIMEDOUT; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_ALLOCATED; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_FREED; + _GLOBAL_CONST signed long IOTMQTT_WRN_NO_MORE_MESSAGES; + _GLOBAL_CONST signed long IOTMQTT_WRN_FAILURE_SENDING; + _GLOBAL_CONST signed long IOTMQTT_WRN_FIFO_EMPTY; + _GLOBAL_CONST signed long IOTMQTT_WRN_CLIENT_DISABLED; + _GLOBAL_CONST signed long IOTMQTT_WRN_INVALID_DATA_RCVD; + _GLOBAL_CONST signed long IOTMQTT_NO_ERR; + _GLOBAL_CONST unsigned short MAX_SUBSCRIPTION_TOPICS; + _GLOBAL_CONST unsigned short MAX_ENTRIES_RECEIVED_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_PUBLISH_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_SUBSCRIBE_OBJECTS; + _GLOBAL_CONST unsigned short MAX_MESSAGE_TOKEN_TABLE; + _GLOBAL_CONST unsigned short MAX_PUBLISH_FUBS; + _GLOBAL_CONST unsigned short MAX_SUBSCRIBE_FUBS; +#endif + + + + +/* Datatypes and datatypes of function blocks */ +typedef enum IotMqttConnTypeEnum +{ IotMqtt_TCP, + IotMqtt_WS +} IotMqttConnTypeEnum; + +typedef enum IotMqttQosEnum +{ IotMqtt_QoS0 = 0, + IotMqtt_QoS1 = 1, + IotMqtt_QoS2 = 2 +} IotMqttQosEnum; + +typedef enum IotMqttPublishModeEnum +{ IOTMQTT_PUB_MODE_TIME, + IOTMQTT_PUB_MODE_TRIGGER, + IOTMQTT_PUB_MODE_VALUE, + IOTMQTT_PUB_MODE_TIME_TRIGGER, + IOTMQTT_PUB_MODE_TIME_VALUE, + IOTMQTT_PUB_MODE_TRIGGER_VALUE, + IOTMQTT_PUB_MODE_TIME_TRG_VALUE +} IotMqttPublishModeEnum; + +typedef enum IotMqttLogLevelEnum +{ IOTMQTT_LOG_LEVEL_ERROR, + IOTMQTT_LOG_LEVEL_PROTOCOL, + IOTMQTT_LOG_LEVEL_MAXIMUM +} IotMqttLogLevelEnum; + +typedef enum IotMqttDataFormatEnum +{ IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON +} IotMqttDataFormatEnum; + +typedef enum IotMqttConnectionStateEnum +{ IOTMQTT_DISABLED, + IOTMQTT_DISCONNECTED, + IOTMQTT_DISCONNECTING, + IOTMQTT_CONNECTED, + IOTMQTT_CONNECTING, + IOTMQTT_CONNECTION_LOST, + IOTMQTT_CONNECTION_ERROR +} IotMqttConnectionStateEnum; + +typedef enum IotMqttGoogleIotJwtAlgorithmEnum +{ IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 +} IotMqttGoogleIotJwtAlgorithmEnum; + +typedef struct IotMqttPayloadType +{ unsigned long pData; + unsigned long Len; +} IotMqttPayloadType; + +typedef struct IotMqttSubscribeInfoType +{ unsigned long NumberOfLostMessages; + unsigned long MessagesInQueue; + unsigned long AvailableMessageSlots; + unsigned long TotalReceivedMessages; +} IotMqttSubscribeInfoType; + +typedef struct IotMqttPublishInfoType +{ unsigned long MessagesPublished; + unsigned long DeliveriesCompleted; + unsigned long PublishErrorCounter; +} IotMqttPublishInfoType; + +typedef struct IotMqttClientParLastWillType +{ plcbit UseLastWill; + unsigned long Topic; + unsigned long Buffer; + unsigned long BufferLength; + enum IotMqttQosEnum QoS; + plcbit Retain; + struct IotMqttPayloadType Payload; +} IotMqttClientParLastWillType; + +typedef struct IotMqttClientParTLSType +{ plcbit UseTLS; + unsigned long CA; + unsigned long Cert; + unsigned long PrivateKey; + unsigned long PrivateKeyPassword; + unsigned long EnabledCipherSuites; + plcbit EnableServerCertAuth; +} IotMqttClientParTLSType; + +typedef struct IotMqttClientParType +{ plcstring ServerUri[256]; + unsigned short Port; + plcstring ClientID[256]; + plcstring UserName[256]; + plcstring Password[256]; + plctime KeepAliveInterval; + struct IotMqttClientParLastWillType LastWill; + plctime ConnectTimeout; + unsigned short MaxInFlight; + plctime MinRetryInterval; + plctime MaxRetryInterval; + struct IotMqttClientParTLSType TLS; + plcbit PersistentData; + plcbit AutomaticReconnect; + enum IotMqttConnTypeEnum ConnectionType; + plcbit CleanSession; + plcbit OfflinePublish; + unsigned short OfflinePublishBuffer; +} IotMqttClientParType; + +typedef struct IotMqttClientInfoType +{ enum IotMqttConnectionStateEnum ConnectionState; + unsigned long NumberActivePublishersFubs; + unsigned long NumberActiveSubscribersFubs; + unsigned long PublishMessageCount; + unsigned long SubscribeMessageCount; + unsigned long PendingMessagesCount; +} IotMqttClientInfoType; + +typedef struct IotMqttReceivedMessageType +{ unsigned long Topic; + unsigned short TopicLen; + unsigned long Buffer; + unsigned long BufferLen; + unsigned char QoS; + plcbit Retained; +} IotMqttReceivedMessageType; + +typedef struct IoTMqttComIdentType +{ unsigned long Internal; + unsigned long pThreadHandle; + unsigned long pThreadAttr; + unsigned long inst; +} IoTMqttComIdentType; + +typedef struct IotMqttConfigParametersType +{ enum IotMqttLogLevelEnum LogLevel; + plcbit UseLogger; + plcstring LoggerName[9]; + unsigned long LoggerSize; + plcbit UseFile; + plcstring LogFileName[81]; + plcstring LogFileDevice[81]; + plcbit AppendTimestamp; + plcbit OverwritteLogs; + plcstring PersistenceFileDevice[81]; +} IotMqttConfigParametersType; + +typedef struct IotMqttGoogleIotParametersType +{ plcstring ProjectID[81]; + plcstring Region[81]; + plcstring RegistryID[81]; + plcstring DeviceID[81]; + plctime ExpirationPeriod; + enum IotMqttGoogleIotJwtAlgorithmEnum Algorithm; +} IotMqttGoogleIotParametersType; + +typedef struct IotMqttClient +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + struct IotMqttClientParType Parameters; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttClientInfoType Info; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Connect; + plcbit ErrorReset; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Error; + plcbit Connected; +} IotMqttClient_typ; + +typedef struct IotMqttPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + plctime SendTimeout; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long Buffer; + unsigned long BufferLength; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + unsigned long _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Send; + plcbit Retained; + /* VAR_OUTPUT (digital) */ + plcbit Busy; + plcbit Active; + plcbit Done; + plcbit Error; + /* VAR (digital) */ + plcbit _Send; + plcbit _Active; + plcbit _ErrorReset; +} IotMqttPublish_typ; + +typedef struct IotMqttRegParPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum QoS; + plctime SendTimeout; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + enum IotMqttPublishModeEnum PublishMode; + plctime SamplingTime; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + struct IotMqttPublish _Publish; + unsigned long _Serializer; + unsigned long _prevPV; + unsigned long _addr; + unsigned long _datalen; + unsigned long _pvname; + enum IotMqttPublishModeEnum _publishmode; + enum IotMqttDataFormatEnum _mode; + plctime _samplingtime; + plctime _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Update; + plcbit Retained; + plcbit Trigger; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Busy; + plcbit Error; + /* VAR (digital) */ + plcbit _Processing; + plcbit _trig; + plcbit _enable; + plcbit _update; + plcbit _pubCmd; +} IotMqttRegParPublish_typ; + +typedef struct IotMqttSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum SubscriptionQoS; + unsigned long RecievedTopic; + unsigned long RecievedTopicSize; + unsigned char QueueSize; + unsigned long Buffer; + unsigned long BufferSize; + /* VAR_OUTPUT (analog) */ + enum IotMqttQosEnum ReceivedQoS; + signed long StatusID; + unsigned long DataSize; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + unsigned long _Internal; + unsigned long _FifoHandle; + unsigned long _FifoLock; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Read; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Subscribed; + plcbit MessageRetrieved; + plcbit Error; + plcbit Busy; + plcbit NewDataValid; + /* VAR (digital) */ + plcbit _Enable; + plcbit _Active; + plcbit _Read; + plcbit _Subscribing; +} IotMqttSubscribe_typ; + +typedef struct IotMqttRegParSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long RecievedTopic; + unsigned long QueueSize; + unsigned long ReceiveBufferSize; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + struct IotMqttSubscribe _Receive; + unsigned long _Parser; + unsigned long _RecvBuffer; + unsigned long _ReceiveBufferSize; + unsigned char _Step; + /* VAR_INPUT (digital) */ + plcbit Enable; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Busy; + plcbit Error; + plcbit UpdateNotification; +} IotMqttRegParSubscribe_typ; + +typedef struct GoogleIotCredentials +{ + /* VAR_INPUT (analog) */ + struct IotMqttGoogleIotParametersType* pIotMqttGoogleIotParameters; + unsigned long pJWT; + unsigned long SizeOfJWT; + struct IotMqttClientParType* pIotMqttClientParameters; + /* VAR (analog) */ + unsigned long _hTask; + /* VAR_INPUT (digital) */ + plcbit Execute; + /* VAR_OUTPUT (digital) */ + plcbit Error; + plcbit Done; + plcbit Busy; + /* VAR (digital) */ + plcbit _Execute; +} GoogleIotCredentials_typ; + + + +/* Prototyping of functions and function blocks */ +_BUR_PUBLIC void IotMqttClient(struct IotMqttClient* inst); +_BUR_PUBLIC void IotMqttPublish(struct IotMqttPublish* inst); +_BUR_PUBLIC void IotMqttRegParPublish(struct IotMqttRegParPublish* inst); +_BUR_PUBLIC void IotMqttSubscribe(struct IotMqttSubscribe* inst); +_BUR_PUBLIC void IotMqttRegParSubscribe(struct IotMqttRegParSubscribe* inst); +_BUR_PUBLIC void GoogleIotCredentials(struct GoogleIotCredentials* inst); +_BUR_PUBLIC signed short IotMqttConfig(struct IotMqttConfigParametersType** ConfigParameters); +_BUR_PUBLIC signed short AzureGenerateDeviceCredentials(unsigned long pConnectionString, unsigned char TimeToLive, unsigned long pParameters, unsigned long PublishTelemetryTopic, unsigned long SizeofPublishTelemetryTopic, unsigned long SubscribeTelemetryTopic, unsigned long SizeofSubscribeTelemetryTopic); + + +#ifdef __cplusplus +}; +#endif +#endif /* _IOTMQTT_ */ + diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/SG4/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/SG4/libIotMqtt.a new file mode 100644 index 0000000..02e63eb Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/SG4/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/Types.typ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/Types.typ new file mode 100644 index 0000000..42ac63c --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.26.0/Types.typ @@ -0,0 +1,159 @@ + +TYPE + IotMqttConnTypeEnum : + ( + IotMqtt_TCP, (*Use standard TCP connection*) + IotMqtt_WS (*Use connection over websockets*) + ); + IotMqttQosEnum : + ( (*The quality of service (QoS) assigned to the message. +*) + IotMqtt_QoS0 := 0, (*Fire and forget - the message may not be delivered*) + IotMqtt_QoS1 := 1, (*At least once - the message will be delivered, but may be delivered more than once in some circumstances*) + IotMqtt_QoS2 := 2 (*Once and one only - the message will be delivered exactly once.*) + ); + IotMqttPublishModeEnum : + ( + IOTMQTT_PUB_MODE_TIME, (*New data is published on a time basis. *) + IOTMQTT_PUB_MODE_TRIGGER, (*New data is published after a trigger. *) + IOTMQTT_PUB_MODE_VALUE, (*New data from the PVs is published after the value of the PV is changed. *) + IOTMQTT_PUB_MODE_TIME_TRIGGER, (*New data is published at a certain time or after a trigger. *) + IOTMQTT_PUB_MODE_TIME_VALUE, (*New data is published at a certain time or after the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TRIGGER_VALUE, (*New data is published after a trigger or the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TIME_TRG_VALUE (*New data is published at a certain time, after the value of the registered PV changes or after a trigger. *) + ); + IotMqttLogLevelEnum : + ( + IOTMQTT_LOG_LEVEL_ERROR, (*Just errors are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_PROTOCOL, (*MQTT protocol operations are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_MAXIMUM (*Diagnosis messages are written to the log file or logger*) + ); + IotMqttDataFormatEnum : + ( + IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON + ); + IotMqttConnectionStateEnum : + ( + IOTMQTT_DISABLED, (*Client FUB is disabled*) + IOTMQTT_DISCONNECTED, (*Client FUB is enabled and disconnected*) + IOTMQTT_DISCONNECTING, (*Client FUB is enabled and disconnecting*) + IOTMQTT_CONNECTED, (*Client FUB is enabled and connected*) + IOTMQTT_CONNECTING, (*Client FUB is enabled and connecting*) + IOTMQTT_CONNECTION_LOST, (*Client FUB is enabled and lost the connection*) + IOTMQTT_CONNECTION_ERROR (*Client FUB is enabled and can't connect*) + ); + IotMqttPayloadType : STRUCT + pData : UDINT; (*Pointer to data buffer*) + Len : UDINT; (*Length of data buffer*) + END_STRUCT; + IotMqttSubscribeInfoType : STRUCT + NumberOfLostMessages : UDINT; (*Number of discarded messages because fifo was full*) + MessagesInQueue : UDINT; (*Number of waiting messages in the fifo*) + AvailableMessageSlots : UDINT; (*Number of available message slots in the fifo*) + TotalReceivedMessages : UDINT; (*Total number of received messages (including discarded messages)*) + END_STRUCT; + IotMqttPublishInfoType : STRUCT + MessagesPublished : UDINT; (*Number of sent messages*) + DeliveriesCompleted : UDINT; (*Number of acknowledged messages (delivery confirmed). Only used when QoS > 0*) + PublishErrorCounter : UDINT; (*Number of errors publishing*) + END_STRUCT; + IotMqttClientParType : STRUCT + ServerUri : STRING[255]; (*String containing broker's URI*) + Port : UINT := 1883; (*TCP port number used to connect to MQTT broker*) + ClientID : STRING[255]; (*String containing ClientID. Must be unique inside the broker*) + UserName : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the user name parameter*) + Password : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the password parameter*) + KeepAliveInterval : TIME := T#30s; (*The "keep alive" interval, defines the maximum time +that should pass without communication between the client and the server +The client will ensure that at least one message travels across the +network within each keep alive period. In the absence of a data-related +message during the time period, the client sends a very small MQTT +"ping" message, which the server will acknowledge. The keep alive +interval enables the client to detect when the server is no longer +available without having to wait for the long TCP/IP timeout. +Set to 0 if you do not want any keep alive processing.*) + LastWill : IotMqttClientParLastWillType; (*LastWill is enabled when the Topic Pointer is set*) + ConnectTimeout : TIME; (*The time interval to allow a connect to complete*) + MaxInFlight : UINT; (*This controls how many messages can be in-flight simultaneously.*) + MinRetryInterval : TIME; (*Minimum retry interval . Doubled on each failed retry*) + MaxRetryInterval : TIME; (*Maximum retry interval . The doubling stops here on failed retries.*) + TLS : IotMqttClientParTLSType; (*TLS parameters*) + PersistentData : BOOL; (*Enables persistentData on QOS > 0 items*) + AutomaticReconnect : BOOL := TRUE; (*Reconnect automatically in the case of a connection being lost*) + ConnectionType : IotMqttConnTypeEnum := IotMqtt_TCP; (*Determines if the connection will use standard TCP or WebSockets*) + CleanSession : BOOL; (*When cleansession is true, the state information is discarded at connect and disconnect. Setting cleansession to false keeps the state information*) + OfflinePublish : {REDUND_UNREPLICABLE} BOOL := FALSE; (*Whether to allow messages to be sent when the client is not connected.*) + OfflinePublishBuffer : UINT := 100; (*The maximum number of messages allowed to be buffered while not connected.*) + END_STRUCT; + IotMqttClientParTLSType : STRUCT + UseTLS : BOOL; (*Set to TRUE if TLS encryption is needed*) + CA : UDINT; (*Pointer to string. Name of the ca certificate stored in the CertificateStore*) + Cert : UDINT; (*Pointer to string. Name of the client certificate file stored in the CertificateStore*) + PrivateKey : UDINT; (*Pointer to string. Name of the private key file stored in the CertificateStore*) + PrivateKeyPassword : UDINT; (*Pointer to string. The password to load the client's privateKey if encrypted*) + EnabledCipherSuites : UDINT; (*Pointer to String.The list of cipher suites that the client will present to the server during the SSL handshake. For a +full explanation of the cipher list format, please see the OpenSSL on-line documentation: +http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT +If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding +those offering no encryption- will be considered. +This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).*) + EnableServerCertAuth : BOOL; (*True/False option to enable verification of the server certificate*) + END_STRUCT; + IotMqttClientParLastWillType : STRUCT + UseLastWill : BOOL; (*Makes use of last will and testament feature*) + Topic : UDINT; (*Pointer to NULL terminated string containing topic of the message*) + Buffer : UDINT; (*Pointer to NULL terminated string with the content of the message*) + BufferLength : UDINT; (*Bufferlenght to send*) + QoS : IotMqttQosEnum; (*QoS parameter (0 - 2)*) + Retain : BOOL; (*Is the message of type retain?*) + Payload : IotMqttPayloadType; (*Content payload, to be used (instead of Buffer) when sending binary data*) + END_STRUCT; + IotMqttClientInfoType : STRUCT + ConnectionState : IotMqttConnectionStateEnum; (*Unable to find host , Connecting , Connected , Connection Lost , Retrying *) + NumberActivePublishersFubs : UDINT; (*Number of active Publishers FUBs attached to this client*) + NumberActiveSubscribersFubs : UDINT; (*Number of active Subscribers FUBs attached to this client*) + PublishMessageCount : UDINT; (*Total number of messages published by this client since enabled*) + SubscribeMessageCount : UDINT; (*Total number of messages received by this client since enabled*) + PendingMessagesCount : UDINT; (*Total number of messages pendinf of delivery*) + END_STRUCT; + IotMqttReceivedMessageType : STRUCT + Topic : UDINT; (*Pointer to the topic of the message*) + TopicLen : UINT; (*Length of the topic*) + Buffer : UDINT; (*Pointer to the buffer with the content of the message*) + BufferLen : UDINT; (*Length of the message buffer*) + QoS : USINT; (*QoS parameter (0 - 2)*) + Retained : BOOL; (*Is the message of type retain?*) + END_STRUCT; + IoTMqttComIdentType : STRUCT + Internal : UDINT; + pThreadHandle : UDINT; + pThreadAttr : UDINT; + inst : UDINT; + END_STRUCT; + IotMqttConfigParametersType : STRUCT + LogLevel : IotMqttLogLevelEnum := IOTMQTT_LOG_LEVEL_ERROR; (*Log level*) + UseLogger : BOOL := 0; (*Use logger*) + LoggerName : STRING[8] := 'IotMqtt'; (*String containing the logger name. Only used if UseLogger is set*) + LoggerSize : UDINT := 2000000; (*Size of the logger in bytes*) + UseFile : BOOL := 1; (*Use file to output the log results*) + LogFileName : STRING[80] := 'IotMqttLog.txt'; (*String containing the file name. Only used if UseFile is set*) + LogFileDevice : STRING[80] := ''; (*String containing the filedevice name. Only used if UseFile is set*) + AppendTimestamp : BOOL := FALSE; (*A timestamp will be added to the filename so that it generates unique filenames. If disabled and the file already exists, it will be overwritten*) + OverwritteLogs : BOOL := TRUE; (*If set, it will delete previous logs if the name matches and no timestamp is added*) + PersistenceFileDevice : STRING[80] := 'IOTMQTT'; (*String containing the FileDevice for persistence files*) + END_STRUCT; + IotMqttGoogleIotJwtAlgorithmEnum : + ( + IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 + ); + IotMqttGoogleIotParametersType : STRUCT + ProjectID : STRING[80]; + Region : STRING[80]; + RegistryID : STRING[80]; + DeviceID : STRING[80]; + ExpirationPeriod : TIME; (*Token expiration period*) + Algorithm : IotMqttGoogleIotJwtAlgorithmEnum; + END_STRUCT; +END_TYPE diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/Binary.lby b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/Binary.lby new file mode 100644 index 0000000..3a29d50 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/Binary.lby @@ -0,0 +1,21 @@ + + + + + Types.typ + Constants.var + IotMqtt.fun + + + + + + + + + + + + + + \ No newline at end of file diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/Constants.var b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/Constants.var new file mode 100644 index 0000000..dce1395 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/Constants.var @@ -0,0 +1,43 @@ +(*Errors*) +VAR CONSTANT + IOTMQTT_ERR_NOT_FREE_HEAP : DINT := -10000; + IOTMQTT_ERR_NULL_HANDLE : DINT := -10001; + IOTMQTT_ERR_INVALID_HANDLE : DINT := -10002; + IOTMQTT_ERR_CA_CERTIFICATE : DINT := -10003; + IOTMQTT_ERR_CONNECTION_LOST : DINT := -10004; + IOTMQTT_ERR_CONNECTION_FAILED : DINT := -10005; + IOTMQTT_ERR_SUBSCRIBE : DINT := -10006; + IOTMQTT_ERR_FIFO_PUBLISH : DINT := -10007; + IOTMQTT_ERR_FIFO_SUBSCRIBE : DINT := -10008; + IOTMQTT_ERR_WRONG_PUBLISH_PAR : DINT := -10009; + IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR : DINT := -10010; + IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS : DINT := -10011; + IOTMQTT_ERR_WRONG_QUEUE_SIZE : DINT := -10012; + IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE : DINT := -10013; + IOTMQTT_ERR_CONN_REFUSED : DINT := -10014; + IOTMQTT_ERR_SENDING_TIMEDOUT : DINT := -10015; +END_VAR +(*Warnings*) +VAR CONSTANT + IOTMQTT_WRN_ALREADY_ALLOCATED : DINT := -20001; + IOTMQTT_WRN_ALREADY_FREED : DINT := -20002; + IOTMQTT_WRN_NO_MORE_MESSAGES : DINT := -20003; + IOTMQTT_WRN_FAILURE_SENDING : DINT := -20004; + IOTMQTT_WRN_FIFO_EMPTY : DINT := -20005; + IOTMQTT_WRN_CLIENT_DISABLED : DINT := -20006; + IOTMQTT_WRN_INVALID_DATA_RCVD : DINT := -20007; +END_VAR +(*OK*) +VAR CONSTANT + IOTMQTT_NO_ERR : DINT := 0; +END_VAR +(*Constants*) +VAR CONSTANT + MAX_SUBSCRIPTION_TOPICS : UINT := 50; + MAX_ENTRIES_RECEIVED_MESSAGES : UINT := 10; + MAX_ENTRIES_PUBLISH_MESSAGES : UINT := 500; + MAX_ENTRIES_SUBSCRIBE_OBJECTS : UINT := 50; + MAX_MESSAGE_TOKEN_TABLE : UINT := 1000; + MAX_PUBLISH_FUBS : UINT := 50; + MAX_SUBSCRIBE_FUBS : UINT := 50; +END_VAR diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/IotMqtt.fun b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/IotMqtt.fun new file mode 100644 index 0000000..dea6966 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/IotMqtt.fun @@ -0,0 +1,192 @@ + +{REDUND_ERROR} FUNCTION IotMqttConfig : INT (*Allows to configure library parameters. It only takes effect the first time it's called*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + ConfigParameters : REFERENCE TO IotMqttConfigParametersType; + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttClient + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + Connect : {REDUND_UNREPLICABLE} BOOL; (*If the FUB is enabled, attemps to connect with the remote MQTT broker*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Clears the current error*) + Parameters : {REDUND_UNREPLICABLE} IotMqttClientParType; (*Contains the client parameters*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and running*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttClientInfoType; (*Contains client information regarding the actual session*) + Connected : {REDUND_UNREPLICABLE} BOOL; (*TRUE if MQTT client is connected with the remote broker*) + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Send : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. Will send a new message each time is set high*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to data buffer*) + BufferLength : {REDUND_UNREPLICABLE} UDINT; (*Buffer length*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + END_VAR + VAR_OUTPUT + Busy : {REDUND_UNREPLICABLE} BOOL; (*Publishing*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Done : {REDUND_UNREPLICABLE} BOOL; (*Publish done*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Send : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _ErrorReset : {REDUND_UNREPLICABLE} BOOL; + _t0 : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Update : {REDUND_UNREPLICABLE} BOOL; (*Edfe sensitive. Will update the internal values for PvName, Mode, PublishMode and SamplingTime*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + PublishMode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; (*Which event or events will send the PV data?*) + SamplingTime : {REDUND_UNREPLICABLE} TIME; (*Sampling rate used for saving new values (used for time-based send mode). On a change, the new value is only applied on a rising edge of Update*) + Trigger : {REDUND_UNREPLICABLE} BOOL; (*Trigger (used for the recording mode that works with a trigger).*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*Working in serialization + sending*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Publish : {REDUND_UNREPLICABLE} IotMqttPublish; + _Serializer : {REDUND_UNREPLICABLE} UDINT; + _Processing : {REDUND_UNREPLICABLE} BOOL; + _prevPV : {REDUND_UNREPLICABLE} UDINT; + _trig : {REDUND_UNREPLICABLE} BOOL; + _addr : {REDUND_UNREPLICABLE} UDINT; + _datalen : {REDUND_UNREPLICABLE} UDINT; + _enable : {REDUND_UNREPLICABLE} BOOL; + _pvname : {REDUND_UNREPLICABLE} UDINT; + _publishmode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; + _mode : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; + _update : {REDUND_UNREPLICABLE} BOOL; + _samplingtime : {REDUND_UNREPLICABLE} TIME; + _t0 : {REDUND_UNREPLICABLE} TIME; + _pubCmd : {REDUND_UNREPLICABLE} BOOL; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB. Subscription will take place at enable of the FUB, if the associated IotMqttClient FUB is enabled and connected.*) + Read : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. When activaded it will deliver one message from the internal FIFO*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + SubscriptionQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + RecievedTopicSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the received topic buffer*) + QueueSize : {REDUND_UNREPLICABLE} USINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to memory area where the content of the read messages will be stored*) + BufferSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the memory area where the content of the read messages will be stored*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The read message from the FIFO has the "Retain" flag*) + ReceivedQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The read message from the FIFO has this QoS*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Subscribed : {REDUND_UNREPLICABLE} BOOL; (*Subscription completed succesfully*) + MessageRetrieved : {REDUND_UNREPLICABLE} BOOL; (*Read operation completed succesfully*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + NewDataValid : {REDUND_UNREPLICABLE} BOOL; (*Is TRUE if new data was received with the last FB call*) + DataSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the Buffer array used in bytes*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Enable : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _Internal : {REDUND_UNREPLICABLE} UDINT; + _FifoHandle : {REDUND_UNREPLICABLE} UDINT; + _Read : {REDUND_UNREPLICABLE} BOOL; + _Subscribing : {REDUND_UNREPLICABLE} BOOL; + _FifoLock : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + QueueSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The received message has the "Retain" flag*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + UpdateNotification : {REDUND_UNREPLICABLE} BOOL; (*registered PV contains new values. This is automatically reset after one cycle.*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Receive : {REDUND_UNREPLICABLE} IotMqttSubscribe; + _Parser : {REDUND_UNREPLICABLE} UDINT; + _RecvBuffer : {REDUND_UNREPLICABLE} UDINT; + _ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + _Step : {REDUND_UNREPLICABLE} USINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_ERROR} FUNCTION AzureGenerateDeviceCredentials : INT (*Given an AzureIoT Hub device connection string, and the "TimeToLive" parameter, will populate the needed parameters for connecting it*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + pConnectionString : UDINT; (*Pointer to string with the connection string*) + TimeToLive : USINT; (*Time in hours that the password will be valid*) + pParameters : UDINT; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + PublishTelemetryTopic : UDINT; (*Pointer to string to store the publish topic*) + SizeofPublishTelemetryTopic : UDINT; (*Size of PublishTelemetryTopic variable*) + SubscribeTelemetryTopic : UDINT; (*Pointer to string to store the subscribe topic*) + SizeofSubscribeTelemetryTopic : UDINT; (*Size of SubscribeTelemetryTopic variable*) + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK GoogleIotCredentials (*Get JWT token for MQTT connection*) + VAR_INPUT + Execute : {REDUND_UNREPLICABLE} BOOL; + pIotMqttGoogleIotParameters : REFERENCE TO IotMqttGoogleIotParametersType; + pJWT : {REDUND_UNREPLICABLE} UDINT; (*Pointer to string. It will be filled with JWT*) + SizeOfJWT : {REDUND_UNREPLICABLE} UDINT; (*Size of destination JWT string*) + pIotMqttClientParameters : REFERENCE TO IotMqttClientParType; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + END_VAR + VAR_OUTPUT + Error : {REDUND_UNREPLICABLE} BOOL; + Done : {REDUND_UNREPLICABLE} BOOL; + Busy : {REDUND_UNREPLICABLE} BOOL; + END_VAR + VAR + _Execute : {REDUND_UNREPLICABLE} BOOL; + _hTask : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/Arm/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/Arm/IotMqtt.br new file mode 100644 index 0000000..f10a8a2 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/Arm/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/Arm/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/Arm/libIotMqtt.a new file mode 100644 index 0000000..574ced4 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/Arm/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/IotMqtt.br new file mode 100644 index 0000000..3f4e17d Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/IotMqtt.h b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/IotMqtt.h new file mode 100644 index 0000000..5486c25 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/IotMqtt.h @@ -0,0 +1,477 @@ +/* Automation Studio generated header file */ +/* Do not edit ! */ +/* IotMqtt 4.34.0 */ + +#ifndef _IOTMQTT_ +#define _IOTMQTT_ +#ifdef __cplusplus +extern "C" +{ +#endif +#ifndef _IotMqtt_VERSION +#define _IotMqtt_VERSION 4.34.0 +#endif + +#include + +#ifndef _BUR_PUBLIC +#define _BUR_PUBLIC +#endif +#ifdef _SG3 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "brsystem.h" + #include "AsIODiag.h" +#endif +#ifdef _SG4 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "brsystem.h" + #include "AsIODiag.h" +#endif +#ifdef _SGC + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "brsystem.h" + #include "AsIODiag.h" +#endif + + +/* Constants */ +#ifdef _REPLACE_CONST + #define IOTMQTT_ERR_NOT_FREE_HEAP (-10000) + #define IOTMQTT_ERR_NULL_HANDLE (-10001) + #define IOTMQTT_ERR_INVALID_HANDLE (-10002) + #define IOTMQTT_ERR_CA_CERTIFICATE (-10003) + #define IOTMQTT_ERR_CONNECTION_LOST (-10004) + #define IOTMQTT_ERR_CONNECTION_FAILED (-10005) + #define IOTMQTT_ERR_SUBSCRIBE (-10006) + #define IOTMQTT_ERR_FIFO_PUBLISH (-10007) + #define IOTMQTT_ERR_FIFO_SUBSCRIBE (-10008) + #define IOTMQTT_ERR_WRONG_PUBLISH_PAR (-10009) + #define IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR (-10010) + #define IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS (-10011) + #define IOTMQTT_ERR_WRONG_QUEUE_SIZE (-10012) + #define IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE (-10013) + #define IOTMQTT_ERR_CONN_REFUSED (-10014) + #define IOTMQTT_ERR_SENDING_TIMEDOUT (-10015) + #define IOTMQTT_WRN_ALREADY_ALLOCATED (-20001) + #define IOTMQTT_WRN_ALREADY_FREED (-20002) + #define IOTMQTT_WRN_NO_MORE_MESSAGES (-20003) + #define IOTMQTT_WRN_FAILURE_SENDING (-20004) + #define IOTMQTT_WRN_FIFO_EMPTY (-20005) + #define IOTMQTT_WRN_CLIENT_DISABLED (-20006) + #define IOTMQTT_WRN_INVALID_DATA_RCVD (-20007) + #define IOTMQTT_NO_ERR 0 + #define MAX_SUBSCRIPTION_TOPICS 50U + #define MAX_ENTRIES_RECEIVED_MESSAGES 10U + #define MAX_ENTRIES_PUBLISH_MESSAGES 500U + #define MAX_ENTRIES_SUBSCRIBE_OBJECTS 50U + #define MAX_MESSAGE_TOKEN_TABLE 1000U + #define MAX_PUBLISH_FUBS 50U + #define MAX_SUBSCRIBE_FUBS 50U +#else + _GLOBAL_CONST signed long IOTMQTT_ERR_NOT_FREE_HEAP; + _GLOBAL_CONST signed long IOTMQTT_ERR_NULL_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_INVALID_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CA_CERTIFICATE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_LOST; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_FAILED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_PUBLISH; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_PUBLISH_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_QUEUE_SIZE; + _GLOBAL_CONST signed long IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONN_REFUSED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SENDING_TIMEDOUT; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_ALLOCATED; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_FREED; + _GLOBAL_CONST signed long IOTMQTT_WRN_NO_MORE_MESSAGES; + _GLOBAL_CONST signed long IOTMQTT_WRN_FAILURE_SENDING; + _GLOBAL_CONST signed long IOTMQTT_WRN_FIFO_EMPTY; + _GLOBAL_CONST signed long IOTMQTT_WRN_CLIENT_DISABLED; + _GLOBAL_CONST signed long IOTMQTT_WRN_INVALID_DATA_RCVD; + _GLOBAL_CONST signed long IOTMQTT_NO_ERR; + _GLOBAL_CONST unsigned short MAX_SUBSCRIPTION_TOPICS; + _GLOBAL_CONST unsigned short MAX_ENTRIES_RECEIVED_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_PUBLISH_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_SUBSCRIBE_OBJECTS; + _GLOBAL_CONST unsigned short MAX_MESSAGE_TOKEN_TABLE; + _GLOBAL_CONST unsigned short MAX_PUBLISH_FUBS; + _GLOBAL_CONST unsigned short MAX_SUBSCRIBE_FUBS; +#endif + + + + +/* Datatypes and datatypes of function blocks */ +typedef enum IotMqttConnTypeEnum +{ IotMqtt_TCP, + IotMqtt_WS +} IotMqttConnTypeEnum; + +typedef enum IotMqttQosEnum +{ IotMqtt_QoS0 = 0, + IotMqtt_QoS1 = 1, + IotMqtt_QoS2 = 2 +} IotMqttQosEnum; + +typedef enum IotMqttPublishModeEnum +{ IOTMQTT_PUB_MODE_TIME, + IOTMQTT_PUB_MODE_TRIGGER, + IOTMQTT_PUB_MODE_VALUE, + IOTMQTT_PUB_MODE_TIME_TRIGGER, + IOTMQTT_PUB_MODE_TIME_VALUE, + IOTMQTT_PUB_MODE_TRIGGER_VALUE, + IOTMQTT_PUB_MODE_TIME_TRG_VALUE +} IotMqttPublishModeEnum; + +typedef enum IotMqttLogLevelEnum +{ IOTMQTT_LOG_LEVEL_ERROR, + IOTMQTT_LOG_LEVEL_PROTOCOL, + IOTMQTT_LOG_LEVEL_MAXIMUM +} IotMqttLogLevelEnum; + +typedef enum IotMqttDataFormatEnum +{ IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON +} IotMqttDataFormatEnum; + +typedef enum IotMqttConnectionStateEnum +{ IOTMQTT_DISABLED, + IOTMQTT_DISCONNECTED, + IOTMQTT_DISCONNECTING, + IOTMQTT_CONNECTED, + IOTMQTT_CONNECTING, + IOTMQTT_CONNECTION_LOST, + IOTMQTT_CONNECTION_ERROR +} IotMqttConnectionStateEnum; + +typedef enum IotMqttGoogleIotJwtAlgorithmEnum +{ IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 +} IotMqttGoogleIotJwtAlgorithmEnum; + +typedef struct IotMqttPayloadType +{ unsigned long pData; + unsigned long Len; +} IotMqttPayloadType; + +typedef struct IotMqttSubscribeInfoType +{ unsigned long NumberOfLostMessages; + unsigned long MessagesInQueue; + unsigned long AvailableMessageSlots; + unsigned long TotalReceivedMessages; +} IotMqttSubscribeInfoType; + +typedef struct IotMqttPublishInfoType +{ unsigned long MessagesPublished; + unsigned long DeliveriesCompleted; + unsigned long PublishErrorCounter; +} IotMqttPublishInfoType; + +typedef struct IotMqttClientParLastWillType +{ plcbit UseLastWill; + unsigned long Topic; + unsigned long Buffer; + unsigned long BufferLength; + enum IotMqttQosEnum QoS; + plcbit Retain; + struct IotMqttPayloadType Payload; +} IotMqttClientParLastWillType; + +typedef struct IotMqttClientParTLSType +{ plcbit UseTLS; + unsigned long CA; + unsigned long Cert; + unsigned long PrivateKey; + unsigned long PrivateKeyPassword; + unsigned long EnabledCipherSuites; + plcbit EnableServerCertAuth; +} IotMqttClientParTLSType; + +typedef struct IotMqttClientParType +{ plcstring ServerUri[256]; + unsigned short Port; + plcstring ClientID[256]; + plcstring UserName[256]; + plcstring Password[256]; + plctime KeepAliveInterval; + struct IotMqttClientParLastWillType LastWill; + plctime ConnectTimeout; + unsigned short MaxInFlight; + plctime MinRetryInterval; + plctime MaxRetryInterval; + struct IotMqttClientParTLSType TLS; + plcbit PersistentData; + plcbit AutomaticReconnect; + enum IotMqttConnTypeEnum ConnectionType; + plcbit CleanSession; + plcbit OfflinePublish; + unsigned short OfflinePublishBuffer; +} IotMqttClientParType; + +typedef struct IotMqttClientInfoType +{ enum IotMqttConnectionStateEnum ConnectionState; + unsigned long NumberActivePublishersFubs; + unsigned long NumberActiveSubscribersFubs; + unsigned long PublishMessageCount; + unsigned long SubscribeMessageCount; + unsigned long PendingMessagesCount; +} IotMqttClientInfoType; + +typedef struct IotMqttReceivedMessageType +{ unsigned long Topic; + unsigned short TopicLen; + unsigned long Buffer; + unsigned long BufferLen; + unsigned char QoS; + plcbit Retained; +} IotMqttReceivedMessageType; + +typedef struct IoTMqttComIdentType +{ unsigned long Internal; + unsigned long pThreadHandle; + unsigned long pThreadAttr; + unsigned long inst; +} IoTMqttComIdentType; + +typedef struct IotMqttConfigParametersType +{ enum IotMqttLogLevelEnum LogLevel; + plcbit UseLogger; + plcstring LoggerName[9]; + unsigned long LoggerSize; + plcbit UseFile; + plcstring LogFileName[81]; + plcstring LogFileDevice[81]; + plcbit AppendTimestamp; + plcbit OverwritteLogs; + plcstring PersistenceFileDevice[81]; +} IotMqttConfigParametersType; + +typedef struct IotMqttGoogleIotParametersType +{ plcstring ProjectID[81]; + plcstring Region[81]; + plcstring RegistryID[81]; + plcstring DeviceID[81]; + plctime ExpirationPeriod; + enum IotMqttGoogleIotJwtAlgorithmEnum Algorithm; +} IotMqttGoogleIotParametersType; + +typedef struct IotMqttClient +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + struct IotMqttClientParType Parameters; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttClientInfoType Info; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Connect; + plcbit ErrorReset; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Error; + plcbit Connected; +} IotMqttClient_typ; + +typedef struct IotMqttPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + plctime SendTimeout; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long Buffer; + unsigned long BufferLength; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + unsigned long _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Send; + plcbit Retained; + /* VAR_OUTPUT (digital) */ + plcbit Busy; + plcbit Active; + plcbit Done; + plcbit Error; + /* VAR (digital) */ + plcbit _Send; + plcbit _Active; + plcbit _ErrorReset; +} IotMqttPublish_typ; + +typedef struct IotMqttRegParPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum QoS; + plctime SendTimeout; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + enum IotMqttPublishModeEnum PublishMode; + plctime SamplingTime; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + struct IotMqttPublish _Publish; + unsigned long _Serializer; + unsigned long _prevPV; + unsigned long _addr; + unsigned long _datalen; + unsigned long _pvname; + enum IotMqttPublishModeEnum _publishmode; + enum IotMqttDataFormatEnum _mode; + plctime _samplingtime; + plctime _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Update; + plcbit Retained; + plcbit Trigger; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Busy; + plcbit Error; + /* VAR (digital) */ + plcbit _Processing; + plcbit _trig; + plcbit _enable; + plcbit _update; + plcbit _pubCmd; +} IotMqttRegParPublish_typ; + +typedef struct IotMqttSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum SubscriptionQoS; + unsigned long RecievedTopic; + unsigned long RecievedTopicSize; + unsigned char QueueSize; + unsigned long Buffer; + unsigned long BufferSize; + /* VAR_OUTPUT (analog) */ + enum IotMqttQosEnum ReceivedQoS; + signed long StatusID; + unsigned long DataSize; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + unsigned long _Internal; + unsigned long _FifoHandle; + unsigned long _FifoLock; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Read; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Subscribed; + plcbit MessageRetrieved; + plcbit Error; + plcbit Busy; + plcbit NewDataValid; + /* VAR (digital) */ + plcbit _Enable; + plcbit _Active; + plcbit _Read; + plcbit _Subscribing; +} IotMqttSubscribe_typ; + +typedef struct IotMqttRegParSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long RecievedTopic; + unsigned long QueueSize; + unsigned long ReceiveBufferSize; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + struct IotMqttSubscribe _Receive; + unsigned long _Parser; + unsigned long _RecvBuffer; + unsigned long _ReceiveBufferSize; + unsigned char _Step; + /* VAR_INPUT (digital) */ + plcbit Enable; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Busy; + plcbit Error; + plcbit UpdateNotification; +} IotMqttRegParSubscribe_typ; + +typedef struct GoogleIotCredentials +{ + /* VAR_INPUT (analog) */ + struct IotMqttGoogleIotParametersType* pIotMqttGoogleIotParameters; + unsigned long pJWT; + unsigned long SizeOfJWT; + struct IotMqttClientParType* pIotMqttClientParameters; + /* VAR (analog) */ + unsigned long _hTask; + /* VAR_INPUT (digital) */ + plcbit Execute; + /* VAR_OUTPUT (digital) */ + plcbit Error; + plcbit Done; + plcbit Busy; + /* VAR (digital) */ + plcbit _Execute; +} GoogleIotCredentials_typ; + + + +/* Prototyping of functions and function blocks */ +_BUR_PUBLIC void IotMqttClient(struct IotMqttClient* inst); +_BUR_PUBLIC void IotMqttPublish(struct IotMqttPublish* inst); +_BUR_PUBLIC void IotMqttRegParPublish(struct IotMqttRegParPublish* inst); +_BUR_PUBLIC void IotMqttSubscribe(struct IotMqttSubscribe* inst); +_BUR_PUBLIC void IotMqttRegParSubscribe(struct IotMqttRegParSubscribe* inst); +_BUR_PUBLIC void GoogleIotCredentials(struct GoogleIotCredentials* inst); +_BUR_PUBLIC signed short IotMqttConfig(struct IotMqttConfigParametersType** ConfigParameters); +_BUR_PUBLIC signed short AzureGenerateDeviceCredentials(unsigned long pConnectionString, unsigned char TimeToLive, unsigned long pParameters, unsigned long PublishTelemetryTopic, unsigned long SizeofPublishTelemetryTopic, unsigned long SubscribeTelemetryTopic, unsigned long SizeofSubscribeTelemetryTopic); + + +#ifdef __cplusplus +}; +#endif +#endif /* _IOTMQTT_ */ + diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/libIotMqtt.a new file mode 100644 index 0000000..02e63eb Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/SG4/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/Types.typ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/Types.typ new file mode 100644 index 0000000..42ac63c --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.34.0/Types.typ @@ -0,0 +1,159 @@ + +TYPE + IotMqttConnTypeEnum : + ( + IotMqtt_TCP, (*Use standard TCP connection*) + IotMqtt_WS (*Use connection over websockets*) + ); + IotMqttQosEnum : + ( (*The quality of service (QoS) assigned to the message. +*) + IotMqtt_QoS0 := 0, (*Fire and forget - the message may not be delivered*) + IotMqtt_QoS1 := 1, (*At least once - the message will be delivered, but may be delivered more than once in some circumstances*) + IotMqtt_QoS2 := 2 (*Once and one only - the message will be delivered exactly once.*) + ); + IotMqttPublishModeEnum : + ( + IOTMQTT_PUB_MODE_TIME, (*New data is published on a time basis. *) + IOTMQTT_PUB_MODE_TRIGGER, (*New data is published after a trigger. *) + IOTMQTT_PUB_MODE_VALUE, (*New data from the PVs is published after the value of the PV is changed. *) + IOTMQTT_PUB_MODE_TIME_TRIGGER, (*New data is published at a certain time or after a trigger. *) + IOTMQTT_PUB_MODE_TIME_VALUE, (*New data is published at a certain time or after the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TRIGGER_VALUE, (*New data is published after a trigger or the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TIME_TRG_VALUE (*New data is published at a certain time, after the value of the registered PV changes or after a trigger. *) + ); + IotMqttLogLevelEnum : + ( + IOTMQTT_LOG_LEVEL_ERROR, (*Just errors are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_PROTOCOL, (*MQTT protocol operations are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_MAXIMUM (*Diagnosis messages are written to the log file or logger*) + ); + IotMqttDataFormatEnum : + ( + IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON + ); + IotMqttConnectionStateEnum : + ( + IOTMQTT_DISABLED, (*Client FUB is disabled*) + IOTMQTT_DISCONNECTED, (*Client FUB is enabled and disconnected*) + IOTMQTT_DISCONNECTING, (*Client FUB is enabled and disconnecting*) + IOTMQTT_CONNECTED, (*Client FUB is enabled and connected*) + IOTMQTT_CONNECTING, (*Client FUB is enabled and connecting*) + IOTMQTT_CONNECTION_LOST, (*Client FUB is enabled and lost the connection*) + IOTMQTT_CONNECTION_ERROR (*Client FUB is enabled and can't connect*) + ); + IotMqttPayloadType : STRUCT + pData : UDINT; (*Pointer to data buffer*) + Len : UDINT; (*Length of data buffer*) + END_STRUCT; + IotMqttSubscribeInfoType : STRUCT + NumberOfLostMessages : UDINT; (*Number of discarded messages because fifo was full*) + MessagesInQueue : UDINT; (*Number of waiting messages in the fifo*) + AvailableMessageSlots : UDINT; (*Number of available message slots in the fifo*) + TotalReceivedMessages : UDINT; (*Total number of received messages (including discarded messages)*) + END_STRUCT; + IotMqttPublishInfoType : STRUCT + MessagesPublished : UDINT; (*Number of sent messages*) + DeliveriesCompleted : UDINT; (*Number of acknowledged messages (delivery confirmed). Only used when QoS > 0*) + PublishErrorCounter : UDINT; (*Number of errors publishing*) + END_STRUCT; + IotMqttClientParType : STRUCT + ServerUri : STRING[255]; (*String containing broker's URI*) + Port : UINT := 1883; (*TCP port number used to connect to MQTT broker*) + ClientID : STRING[255]; (*String containing ClientID. Must be unique inside the broker*) + UserName : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the user name parameter*) + Password : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the password parameter*) + KeepAliveInterval : TIME := T#30s; (*The "keep alive" interval, defines the maximum time +that should pass without communication between the client and the server +The client will ensure that at least one message travels across the +network within each keep alive period. In the absence of a data-related +message during the time period, the client sends a very small MQTT +"ping" message, which the server will acknowledge. The keep alive +interval enables the client to detect when the server is no longer +available without having to wait for the long TCP/IP timeout. +Set to 0 if you do not want any keep alive processing.*) + LastWill : IotMqttClientParLastWillType; (*LastWill is enabled when the Topic Pointer is set*) + ConnectTimeout : TIME; (*The time interval to allow a connect to complete*) + MaxInFlight : UINT; (*This controls how many messages can be in-flight simultaneously.*) + MinRetryInterval : TIME; (*Minimum retry interval . Doubled on each failed retry*) + MaxRetryInterval : TIME; (*Maximum retry interval . The doubling stops here on failed retries.*) + TLS : IotMqttClientParTLSType; (*TLS parameters*) + PersistentData : BOOL; (*Enables persistentData on QOS > 0 items*) + AutomaticReconnect : BOOL := TRUE; (*Reconnect automatically in the case of a connection being lost*) + ConnectionType : IotMqttConnTypeEnum := IotMqtt_TCP; (*Determines if the connection will use standard TCP or WebSockets*) + CleanSession : BOOL; (*When cleansession is true, the state information is discarded at connect and disconnect. Setting cleansession to false keeps the state information*) + OfflinePublish : {REDUND_UNREPLICABLE} BOOL := FALSE; (*Whether to allow messages to be sent when the client is not connected.*) + OfflinePublishBuffer : UINT := 100; (*The maximum number of messages allowed to be buffered while not connected.*) + END_STRUCT; + IotMqttClientParTLSType : STRUCT + UseTLS : BOOL; (*Set to TRUE if TLS encryption is needed*) + CA : UDINT; (*Pointer to string. Name of the ca certificate stored in the CertificateStore*) + Cert : UDINT; (*Pointer to string. Name of the client certificate file stored in the CertificateStore*) + PrivateKey : UDINT; (*Pointer to string. Name of the private key file stored in the CertificateStore*) + PrivateKeyPassword : UDINT; (*Pointer to string. The password to load the client's privateKey if encrypted*) + EnabledCipherSuites : UDINT; (*Pointer to String.The list of cipher suites that the client will present to the server during the SSL handshake. For a +full explanation of the cipher list format, please see the OpenSSL on-line documentation: +http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT +If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding +those offering no encryption- will be considered. +This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).*) + EnableServerCertAuth : BOOL; (*True/False option to enable verification of the server certificate*) + END_STRUCT; + IotMqttClientParLastWillType : STRUCT + UseLastWill : BOOL; (*Makes use of last will and testament feature*) + Topic : UDINT; (*Pointer to NULL terminated string containing topic of the message*) + Buffer : UDINT; (*Pointer to NULL terminated string with the content of the message*) + BufferLength : UDINT; (*Bufferlenght to send*) + QoS : IotMqttQosEnum; (*QoS parameter (0 - 2)*) + Retain : BOOL; (*Is the message of type retain?*) + Payload : IotMqttPayloadType; (*Content payload, to be used (instead of Buffer) when sending binary data*) + END_STRUCT; + IotMqttClientInfoType : STRUCT + ConnectionState : IotMqttConnectionStateEnum; (*Unable to find host , Connecting , Connected , Connection Lost , Retrying *) + NumberActivePublishersFubs : UDINT; (*Number of active Publishers FUBs attached to this client*) + NumberActiveSubscribersFubs : UDINT; (*Number of active Subscribers FUBs attached to this client*) + PublishMessageCount : UDINT; (*Total number of messages published by this client since enabled*) + SubscribeMessageCount : UDINT; (*Total number of messages received by this client since enabled*) + PendingMessagesCount : UDINT; (*Total number of messages pendinf of delivery*) + END_STRUCT; + IotMqttReceivedMessageType : STRUCT + Topic : UDINT; (*Pointer to the topic of the message*) + TopicLen : UINT; (*Length of the topic*) + Buffer : UDINT; (*Pointer to the buffer with the content of the message*) + BufferLen : UDINT; (*Length of the message buffer*) + QoS : USINT; (*QoS parameter (0 - 2)*) + Retained : BOOL; (*Is the message of type retain?*) + END_STRUCT; + IoTMqttComIdentType : STRUCT + Internal : UDINT; + pThreadHandle : UDINT; + pThreadAttr : UDINT; + inst : UDINT; + END_STRUCT; + IotMqttConfigParametersType : STRUCT + LogLevel : IotMqttLogLevelEnum := IOTMQTT_LOG_LEVEL_ERROR; (*Log level*) + UseLogger : BOOL := 0; (*Use logger*) + LoggerName : STRING[8] := 'IotMqtt'; (*String containing the logger name. Only used if UseLogger is set*) + LoggerSize : UDINT := 2000000; (*Size of the logger in bytes*) + UseFile : BOOL := 1; (*Use file to output the log results*) + LogFileName : STRING[80] := 'IotMqttLog.txt'; (*String containing the file name. Only used if UseFile is set*) + LogFileDevice : STRING[80] := ''; (*String containing the filedevice name. Only used if UseFile is set*) + AppendTimestamp : BOOL := FALSE; (*A timestamp will be added to the filename so that it generates unique filenames. If disabled and the file already exists, it will be overwritten*) + OverwritteLogs : BOOL := TRUE; (*If set, it will delete previous logs if the name matches and no timestamp is added*) + PersistenceFileDevice : STRING[80] := 'IOTMQTT'; (*String containing the FileDevice for persistence files*) + END_STRUCT; + IotMqttGoogleIotJwtAlgorithmEnum : + ( + IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 + ); + IotMqttGoogleIotParametersType : STRUCT + ProjectID : STRING[80]; + Region : STRING[80]; + RegistryID : STRING[80]; + DeviceID : STRING[80]; + ExpirationPeriod : TIME; (*Token expiration period*) + Algorithm : IotMqttGoogleIotJwtAlgorithmEnum; + END_STRUCT; +END_TYPE diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/Binary.lby b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/Binary.lby new file mode 100644 index 0000000..0039929 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/Binary.lby @@ -0,0 +1,20 @@ + + + + + Types.typ + Constants.var + IotMqtt.fun + + + + + + + + + + + + + \ No newline at end of file diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/Constants.var b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/Constants.var new file mode 100644 index 0000000..dce1395 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/Constants.var @@ -0,0 +1,43 @@ +(*Errors*) +VAR CONSTANT + IOTMQTT_ERR_NOT_FREE_HEAP : DINT := -10000; + IOTMQTT_ERR_NULL_HANDLE : DINT := -10001; + IOTMQTT_ERR_INVALID_HANDLE : DINT := -10002; + IOTMQTT_ERR_CA_CERTIFICATE : DINT := -10003; + IOTMQTT_ERR_CONNECTION_LOST : DINT := -10004; + IOTMQTT_ERR_CONNECTION_FAILED : DINT := -10005; + IOTMQTT_ERR_SUBSCRIBE : DINT := -10006; + IOTMQTT_ERR_FIFO_PUBLISH : DINT := -10007; + IOTMQTT_ERR_FIFO_SUBSCRIBE : DINT := -10008; + IOTMQTT_ERR_WRONG_PUBLISH_PAR : DINT := -10009; + IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR : DINT := -10010; + IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS : DINT := -10011; + IOTMQTT_ERR_WRONG_QUEUE_SIZE : DINT := -10012; + IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE : DINT := -10013; + IOTMQTT_ERR_CONN_REFUSED : DINT := -10014; + IOTMQTT_ERR_SENDING_TIMEDOUT : DINT := -10015; +END_VAR +(*Warnings*) +VAR CONSTANT + IOTMQTT_WRN_ALREADY_ALLOCATED : DINT := -20001; + IOTMQTT_WRN_ALREADY_FREED : DINT := -20002; + IOTMQTT_WRN_NO_MORE_MESSAGES : DINT := -20003; + IOTMQTT_WRN_FAILURE_SENDING : DINT := -20004; + IOTMQTT_WRN_FIFO_EMPTY : DINT := -20005; + IOTMQTT_WRN_CLIENT_DISABLED : DINT := -20006; + IOTMQTT_WRN_INVALID_DATA_RCVD : DINT := -20007; +END_VAR +(*OK*) +VAR CONSTANT + IOTMQTT_NO_ERR : DINT := 0; +END_VAR +(*Constants*) +VAR CONSTANT + MAX_SUBSCRIPTION_TOPICS : UINT := 50; + MAX_ENTRIES_RECEIVED_MESSAGES : UINT := 10; + MAX_ENTRIES_PUBLISH_MESSAGES : UINT := 500; + MAX_ENTRIES_SUBSCRIBE_OBJECTS : UINT := 50; + MAX_MESSAGE_TOKEN_TABLE : UINT := 1000; + MAX_PUBLISH_FUBS : UINT := 50; + MAX_SUBSCRIBE_FUBS : UINT := 50; +END_VAR diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/IotMqtt.fun b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/IotMqtt.fun new file mode 100644 index 0000000..dea6966 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/IotMqtt.fun @@ -0,0 +1,192 @@ + +{REDUND_ERROR} FUNCTION IotMqttConfig : INT (*Allows to configure library parameters. It only takes effect the first time it's called*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + ConfigParameters : REFERENCE TO IotMqttConfigParametersType; + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttClient + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + Connect : {REDUND_UNREPLICABLE} BOOL; (*If the FUB is enabled, attemps to connect with the remote MQTT broker*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Clears the current error*) + Parameters : {REDUND_UNREPLICABLE} IotMqttClientParType; (*Contains the client parameters*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and running*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttClientInfoType; (*Contains client information regarding the actual session*) + Connected : {REDUND_UNREPLICABLE} BOOL; (*TRUE if MQTT client is connected with the remote broker*) + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Send : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. Will send a new message each time is set high*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to data buffer*) + BufferLength : {REDUND_UNREPLICABLE} UDINT; (*Buffer length*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + END_VAR + VAR_OUTPUT + Busy : {REDUND_UNREPLICABLE} BOOL; (*Publishing*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Done : {REDUND_UNREPLICABLE} BOOL; (*Publish done*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Send : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _ErrorReset : {REDUND_UNREPLICABLE} BOOL; + _t0 : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Update : {REDUND_UNREPLICABLE} BOOL; (*Edfe sensitive. Will update the internal values for PvName, Mode, PublishMode and SamplingTime*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + PublishMode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; (*Which event or events will send the PV data?*) + SamplingTime : {REDUND_UNREPLICABLE} TIME; (*Sampling rate used for saving new values (used for time-based send mode). On a change, the new value is only applied on a rising edge of Update*) + Trigger : {REDUND_UNREPLICABLE} BOOL; (*Trigger (used for the recording mode that works with a trigger).*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*Working in serialization + sending*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Publish : {REDUND_UNREPLICABLE} IotMqttPublish; + _Serializer : {REDUND_UNREPLICABLE} UDINT; + _Processing : {REDUND_UNREPLICABLE} BOOL; + _prevPV : {REDUND_UNREPLICABLE} UDINT; + _trig : {REDUND_UNREPLICABLE} BOOL; + _addr : {REDUND_UNREPLICABLE} UDINT; + _datalen : {REDUND_UNREPLICABLE} UDINT; + _enable : {REDUND_UNREPLICABLE} BOOL; + _pvname : {REDUND_UNREPLICABLE} UDINT; + _publishmode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; + _mode : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; + _update : {REDUND_UNREPLICABLE} BOOL; + _samplingtime : {REDUND_UNREPLICABLE} TIME; + _t0 : {REDUND_UNREPLICABLE} TIME; + _pubCmd : {REDUND_UNREPLICABLE} BOOL; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB. Subscription will take place at enable of the FUB, if the associated IotMqttClient FUB is enabled and connected.*) + Read : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. When activaded it will deliver one message from the internal FIFO*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + SubscriptionQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + RecievedTopicSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the received topic buffer*) + QueueSize : {REDUND_UNREPLICABLE} USINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to memory area where the content of the read messages will be stored*) + BufferSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the memory area where the content of the read messages will be stored*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The read message from the FIFO has the "Retain" flag*) + ReceivedQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The read message from the FIFO has this QoS*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Subscribed : {REDUND_UNREPLICABLE} BOOL; (*Subscription completed succesfully*) + MessageRetrieved : {REDUND_UNREPLICABLE} BOOL; (*Read operation completed succesfully*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + NewDataValid : {REDUND_UNREPLICABLE} BOOL; (*Is TRUE if new data was received with the last FB call*) + DataSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the Buffer array used in bytes*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Enable : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _Internal : {REDUND_UNREPLICABLE} UDINT; + _FifoHandle : {REDUND_UNREPLICABLE} UDINT; + _Read : {REDUND_UNREPLICABLE} BOOL; + _Subscribing : {REDUND_UNREPLICABLE} BOOL; + _FifoLock : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + QueueSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The received message has the "Retain" flag*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + UpdateNotification : {REDUND_UNREPLICABLE} BOOL; (*registered PV contains new values. This is automatically reset after one cycle.*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Receive : {REDUND_UNREPLICABLE} IotMqttSubscribe; + _Parser : {REDUND_UNREPLICABLE} UDINT; + _RecvBuffer : {REDUND_UNREPLICABLE} UDINT; + _ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + _Step : {REDUND_UNREPLICABLE} USINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_ERROR} FUNCTION AzureGenerateDeviceCredentials : INT (*Given an AzureIoT Hub device connection string, and the "TimeToLive" parameter, will populate the needed parameters for connecting it*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + pConnectionString : UDINT; (*Pointer to string with the connection string*) + TimeToLive : USINT; (*Time in hours that the password will be valid*) + pParameters : UDINT; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + PublishTelemetryTopic : UDINT; (*Pointer to string to store the publish topic*) + SizeofPublishTelemetryTopic : UDINT; (*Size of PublishTelemetryTopic variable*) + SubscribeTelemetryTopic : UDINT; (*Pointer to string to store the subscribe topic*) + SizeofSubscribeTelemetryTopic : UDINT; (*Size of SubscribeTelemetryTopic variable*) + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK GoogleIotCredentials (*Get JWT token for MQTT connection*) + VAR_INPUT + Execute : {REDUND_UNREPLICABLE} BOOL; + pIotMqttGoogleIotParameters : REFERENCE TO IotMqttGoogleIotParametersType; + pJWT : {REDUND_UNREPLICABLE} UDINT; (*Pointer to string. It will be filled with JWT*) + SizeOfJWT : {REDUND_UNREPLICABLE} UDINT; (*Size of destination JWT string*) + pIotMqttClientParameters : REFERENCE TO IotMqttClientParType; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + END_VAR + VAR_OUTPUT + Error : {REDUND_UNREPLICABLE} BOOL; + Done : {REDUND_UNREPLICABLE} BOOL; + Busy : {REDUND_UNREPLICABLE} BOOL; + END_VAR + VAR + _Execute : {REDUND_UNREPLICABLE} BOOL; + _hTask : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/Arm/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/Arm/IotMqtt.br new file mode 100644 index 0000000..6b4cea3 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/Arm/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/Arm/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/Arm/libIotMqtt.a new file mode 100644 index 0000000..4425429 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/Arm/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/IotMqtt.br new file mode 100644 index 0000000..9c0957c Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/IotMqtt.h b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/IotMqtt.h new file mode 100644 index 0000000..a703aab --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/IotMqtt.h @@ -0,0 +1,474 @@ +/* Automation Studio generated header file */ +/* Do not edit ! */ +/* IotMqtt 4.53.0 */ + +#ifndef _IOTMQTT_ +#define _IOTMQTT_ +#ifdef __cplusplus +extern "C" +{ +#endif +#ifndef _IotMqtt_VERSION +#define _IotMqtt_VERSION 4.53.0 +#endif + +#include + +#ifndef _BUR_PUBLIC +#define _BUR_PUBLIC +#endif +#ifdef _SG3 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif +#ifdef _SG4 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif +#ifdef _SGC + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif + + +/* Constants */ +#ifdef _REPLACE_CONST + #define IOTMQTT_ERR_NOT_FREE_HEAP (-10000) + #define IOTMQTT_ERR_NULL_HANDLE (-10001) + #define IOTMQTT_ERR_INVALID_HANDLE (-10002) + #define IOTMQTT_ERR_CA_CERTIFICATE (-10003) + #define IOTMQTT_ERR_CONNECTION_LOST (-10004) + #define IOTMQTT_ERR_CONNECTION_FAILED (-10005) + #define IOTMQTT_ERR_SUBSCRIBE (-10006) + #define IOTMQTT_ERR_FIFO_PUBLISH (-10007) + #define IOTMQTT_ERR_FIFO_SUBSCRIBE (-10008) + #define IOTMQTT_ERR_WRONG_PUBLISH_PAR (-10009) + #define IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR (-10010) + #define IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS (-10011) + #define IOTMQTT_ERR_WRONG_QUEUE_SIZE (-10012) + #define IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE (-10013) + #define IOTMQTT_ERR_CONN_REFUSED (-10014) + #define IOTMQTT_ERR_SENDING_TIMEDOUT (-10015) + #define IOTMQTT_WRN_ALREADY_ALLOCATED (-20001) + #define IOTMQTT_WRN_ALREADY_FREED (-20002) + #define IOTMQTT_WRN_NO_MORE_MESSAGES (-20003) + #define IOTMQTT_WRN_FAILURE_SENDING (-20004) + #define IOTMQTT_WRN_FIFO_EMPTY (-20005) + #define IOTMQTT_WRN_CLIENT_DISABLED (-20006) + #define IOTMQTT_WRN_INVALID_DATA_RCVD (-20007) + #define IOTMQTT_NO_ERR 0 + #define MAX_SUBSCRIPTION_TOPICS 50U + #define MAX_ENTRIES_RECEIVED_MESSAGES 10U + #define MAX_ENTRIES_PUBLISH_MESSAGES 500U + #define MAX_ENTRIES_SUBSCRIBE_OBJECTS 50U + #define MAX_MESSAGE_TOKEN_TABLE 1000U + #define MAX_PUBLISH_FUBS 50U + #define MAX_SUBSCRIBE_FUBS 50U +#else + _GLOBAL_CONST signed long IOTMQTT_ERR_NOT_FREE_HEAP; + _GLOBAL_CONST signed long IOTMQTT_ERR_NULL_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_INVALID_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CA_CERTIFICATE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_LOST; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_FAILED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_PUBLISH; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_PUBLISH_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_QUEUE_SIZE; + _GLOBAL_CONST signed long IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONN_REFUSED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SENDING_TIMEDOUT; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_ALLOCATED; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_FREED; + _GLOBAL_CONST signed long IOTMQTT_WRN_NO_MORE_MESSAGES; + _GLOBAL_CONST signed long IOTMQTT_WRN_FAILURE_SENDING; + _GLOBAL_CONST signed long IOTMQTT_WRN_FIFO_EMPTY; + _GLOBAL_CONST signed long IOTMQTT_WRN_CLIENT_DISABLED; + _GLOBAL_CONST signed long IOTMQTT_WRN_INVALID_DATA_RCVD; + _GLOBAL_CONST signed long IOTMQTT_NO_ERR; + _GLOBAL_CONST unsigned short MAX_SUBSCRIPTION_TOPICS; + _GLOBAL_CONST unsigned short MAX_ENTRIES_RECEIVED_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_PUBLISH_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_SUBSCRIBE_OBJECTS; + _GLOBAL_CONST unsigned short MAX_MESSAGE_TOKEN_TABLE; + _GLOBAL_CONST unsigned short MAX_PUBLISH_FUBS; + _GLOBAL_CONST unsigned short MAX_SUBSCRIBE_FUBS; +#endif + + + + +/* Datatypes and datatypes of function blocks */ +typedef enum IotMqttConnTypeEnum +{ IotMqtt_TCP, + IotMqtt_WS +} IotMqttConnTypeEnum; + +typedef enum IotMqttQosEnum +{ IotMqtt_QoS0 = 0, + IotMqtt_QoS1 = 1, + IotMqtt_QoS2 = 2 +} IotMqttQosEnum; + +typedef enum IotMqttPublishModeEnum +{ IOTMQTT_PUB_MODE_TIME, + IOTMQTT_PUB_MODE_TRIGGER, + IOTMQTT_PUB_MODE_VALUE, + IOTMQTT_PUB_MODE_TIME_TRIGGER, + IOTMQTT_PUB_MODE_TIME_VALUE, + IOTMQTT_PUB_MODE_TRIGGER_VALUE, + IOTMQTT_PUB_MODE_TIME_TRG_VALUE +} IotMqttPublishModeEnum; + +typedef enum IotMqttLogLevelEnum +{ IOTMQTT_LOG_LEVEL_ERROR, + IOTMQTT_LOG_LEVEL_PROTOCOL, + IOTMQTT_LOG_LEVEL_MAXIMUM +} IotMqttLogLevelEnum; + +typedef enum IotMqttDataFormatEnum +{ IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON +} IotMqttDataFormatEnum; + +typedef enum IotMqttConnectionStateEnum +{ IOTMQTT_DISABLED, + IOTMQTT_DISCONNECTED, + IOTMQTT_DISCONNECTING, + IOTMQTT_CONNECTED, + IOTMQTT_CONNECTING, + IOTMQTT_CONNECTION_LOST, + IOTMQTT_CONNECTION_ERROR +} IotMqttConnectionStateEnum; + +typedef enum IotMqttGoogleIotJwtAlgorithmEnum +{ IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 +} IotMqttGoogleIotJwtAlgorithmEnum; + +typedef struct IotMqttPayloadType +{ unsigned long pData; + unsigned long Len; +} IotMqttPayloadType; + +typedef struct IotMqttSubscribeInfoType +{ unsigned long NumberOfLostMessages; + unsigned long MessagesInQueue; + unsigned long AvailableMessageSlots; + unsigned long TotalReceivedMessages; +} IotMqttSubscribeInfoType; + +typedef struct IotMqttPublishInfoType +{ unsigned long MessagesPublished; + unsigned long DeliveriesCompleted; + unsigned long PublishErrorCounter; +} IotMqttPublishInfoType; + +typedef struct IotMqttClientParLastWillType +{ plcbit UseLastWill; + unsigned long Topic; + unsigned long Buffer; + unsigned long BufferLength; + enum IotMqttQosEnum QoS; + plcbit Retain; + struct IotMqttPayloadType Payload; +} IotMqttClientParLastWillType; + +typedef struct IotMqttClientParTLSType +{ plcbit UseTLS; + unsigned long CA; + unsigned long Cert; + unsigned long PrivateKey; + unsigned long PrivateKeyPassword; + unsigned long EnabledCipherSuites; + plcbit EnableServerCertAuth; +} IotMqttClientParTLSType; + +typedef struct IotMqttClientParType +{ plcstring ServerUri[256]; + unsigned short Port; + plcstring ClientID[256]; + plcstring UserName[256]; + plcstring Password[256]; + plctime KeepAliveInterval; + struct IotMqttClientParLastWillType LastWill; + plctime ConnectTimeout; + unsigned short MaxInFlight; + plctime MinRetryInterval; + plctime MaxRetryInterval; + struct IotMqttClientParTLSType TLS; + plcbit PersistentData; + plcbit AutomaticReconnect; + enum IotMqttConnTypeEnum ConnectionType; + plcbit CleanSession; + plcbit OfflinePublish; + unsigned short OfflinePublishBuffer; +} IotMqttClientParType; + +typedef struct IotMqttClientInfoType +{ enum IotMqttConnectionStateEnum ConnectionState; + unsigned long NumberActivePublishersFubs; + unsigned long NumberActiveSubscribersFubs; + unsigned long PublishMessageCount; + unsigned long SubscribeMessageCount; + unsigned long PendingMessagesCount; +} IotMqttClientInfoType; + +typedef struct IotMqttReceivedMessageType +{ unsigned long Topic; + unsigned short TopicLen; + unsigned long Buffer; + unsigned long BufferLen; + unsigned char QoS; + plcbit Retained; +} IotMqttReceivedMessageType; + +typedef struct IoTMqttComIdentType +{ unsigned long Internal; + unsigned long pThreadHandle; + unsigned long pThreadAttr; + unsigned long inst; +} IoTMqttComIdentType; + +typedef struct IotMqttConfigParametersType +{ enum IotMqttLogLevelEnum LogLevel; + plcbit UseLogger; + plcstring LoggerName[9]; + unsigned long LoggerSize; + plcbit UseFile; + plcstring LogFileName[81]; + plcstring LogFileDevice[81]; + plcbit AppendTimestamp; + plcbit OverwritteLogs; + plcstring PersistenceFileDevice[81]; +} IotMqttConfigParametersType; + +typedef struct IotMqttGoogleIotParametersType +{ plcstring ProjectID[81]; + plcstring Region[81]; + plcstring RegistryID[81]; + plcstring DeviceID[81]; + plctime ExpirationPeriod; + enum IotMqttGoogleIotJwtAlgorithmEnum Algorithm; +} IotMqttGoogleIotParametersType; + +typedef struct IotMqttClient +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + struct IotMqttClientParType Parameters; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttClientInfoType Info; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Connect; + plcbit ErrorReset; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Error; + plcbit Connected; +} IotMqttClient_typ; + +typedef struct IotMqttPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + plctime SendTimeout; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long Buffer; + unsigned long BufferLength; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + unsigned long _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Send; + plcbit Retained; + /* VAR_OUTPUT (digital) */ + plcbit Busy; + plcbit Active; + plcbit Done; + plcbit Error; + /* VAR (digital) */ + plcbit _Send; + plcbit _Active; + plcbit _ErrorReset; +} IotMqttPublish_typ; + +typedef struct IotMqttRegParPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum QoS; + plctime SendTimeout; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + enum IotMqttPublishModeEnum PublishMode; + plctime SamplingTime; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + struct IotMqttPublish _Publish; + unsigned long _Serializer; + unsigned long _prevPV; + unsigned long _addr; + unsigned long _datalen; + unsigned long _pvname; + enum IotMqttPublishModeEnum _publishmode; + enum IotMqttDataFormatEnum _mode; + plctime _samplingtime; + plctime _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Update; + plcbit Retained; + plcbit Trigger; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Busy; + plcbit Error; + /* VAR (digital) */ + plcbit _Processing; + plcbit _trig; + plcbit _enable; + plcbit _update; + plcbit _pubCmd; +} IotMqttRegParPublish_typ; + +typedef struct IotMqttSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum SubscriptionQoS; + unsigned long RecievedTopic; + unsigned long RecievedTopicSize; + unsigned char QueueSize; + unsigned long Buffer; + unsigned long BufferSize; + /* VAR_OUTPUT (analog) */ + enum IotMqttQosEnum ReceivedQoS; + signed long StatusID; + unsigned long DataSize; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + unsigned long _Internal; + unsigned long _FifoHandle; + unsigned long _FifoLock; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Read; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Subscribed; + plcbit MessageRetrieved; + plcbit Error; + plcbit Busy; + plcbit NewDataValid; + /* VAR (digital) */ + plcbit _Enable; + plcbit _Active; + plcbit _Read; + plcbit _Subscribing; +} IotMqttSubscribe_typ; + +typedef struct IotMqttRegParSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long RecievedTopic; + unsigned long QueueSize; + unsigned long ReceiveBufferSize; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + struct IotMqttSubscribe _Receive; + unsigned long _Parser; + unsigned long _RecvBuffer; + unsigned long _ReceiveBufferSize; + unsigned char _Step; + /* VAR_INPUT (digital) */ + plcbit Enable; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Busy; + plcbit Error; + plcbit UpdateNotification; +} IotMqttRegParSubscribe_typ; + +typedef struct GoogleIotCredentials +{ + /* VAR_INPUT (analog) */ + struct IotMqttGoogleIotParametersType* pIotMqttGoogleIotParameters; + unsigned long pJWT; + unsigned long SizeOfJWT; + struct IotMqttClientParType* pIotMqttClientParameters; + /* VAR (analog) */ + unsigned long _hTask; + /* VAR_INPUT (digital) */ + plcbit Execute; + /* VAR_OUTPUT (digital) */ + plcbit Error; + plcbit Done; + plcbit Busy; + /* VAR (digital) */ + plcbit _Execute; +} GoogleIotCredentials_typ; + + + +/* Prototyping of functions and function blocks */ +_BUR_PUBLIC void IotMqttClient(struct IotMqttClient* inst); +_BUR_PUBLIC void IotMqttPublish(struct IotMqttPublish* inst); +_BUR_PUBLIC void IotMqttRegParPublish(struct IotMqttRegParPublish* inst); +_BUR_PUBLIC void IotMqttSubscribe(struct IotMqttSubscribe* inst); +_BUR_PUBLIC void IotMqttRegParSubscribe(struct IotMqttRegParSubscribe* inst); +_BUR_PUBLIC void GoogleIotCredentials(struct GoogleIotCredentials* inst); +_BUR_PUBLIC signed short IotMqttConfig(struct IotMqttConfigParametersType** ConfigParameters); +_BUR_PUBLIC signed short AzureGenerateDeviceCredentials(unsigned long pConnectionString, unsigned char TimeToLive, unsigned long pParameters, unsigned long PublishTelemetryTopic, unsigned long SizeofPublishTelemetryTopic, unsigned long SubscribeTelemetryTopic, unsigned long SizeofSubscribeTelemetryTopic); + + +#ifdef __cplusplus +}; +#endif +#endif /* _IOTMQTT_ */ + diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/libIotMqtt.a new file mode 100644 index 0000000..2217229 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/SG4/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/Types.typ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/Types.typ new file mode 100644 index 0000000..42ac63c --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.53.0/Types.typ @@ -0,0 +1,159 @@ + +TYPE + IotMqttConnTypeEnum : + ( + IotMqtt_TCP, (*Use standard TCP connection*) + IotMqtt_WS (*Use connection over websockets*) + ); + IotMqttQosEnum : + ( (*The quality of service (QoS) assigned to the message. +*) + IotMqtt_QoS0 := 0, (*Fire and forget - the message may not be delivered*) + IotMqtt_QoS1 := 1, (*At least once - the message will be delivered, but may be delivered more than once in some circumstances*) + IotMqtt_QoS2 := 2 (*Once and one only - the message will be delivered exactly once.*) + ); + IotMqttPublishModeEnum : + ( + IOTMQTT_PUB_MODE_TIME, (*New data is published on a time basis. *) + IOTMQTT_PUB_MODE_TRIGGER, (*New data is published after a trigger. *) + IOTMQTT_PUB_MODE_VALUE, (*New data from the PVs is published after the value of the PV is changed. *) + IOTMQTT_PUB_MODE_TIME_TRIGGER, (*New data is published at a certain time or after a trigger. *) + IOTMQTT_PUB_MODE_TIME_VALUE, (*New data is published at a certain time or after the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TRIGGER_VALUE, (*New data is published after a trigger or the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TIME_TRG_VALUE (*New data is published at a certain time, after the value of the registered PV changes or after a trigger. *) + ); + IotMqttLogLevelEnum : + ( + IOTMQTT_LOG_LEVEL_ERROR, (*Just errors are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_PROTOCOL, (*MQTT protocol operations are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_MAXIMUM (*Diagnosis messages are written to the log file or logger*) + ); + IotMqttDataFormatEnum : + ( + IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON + ); + IotMqttConnectionStateEnum : + ( + IOTMQTT_DISABLED, (*Client FUB is disabled*) + IOTMQTT_DISCONNECTED, (*Client FUB is enabled and disconnected*) + IOTMQTT_DISCONNECTING, (*Client FUB is enabled and disconnecting*) + IOTMQTT_CONNECTED, (*Client FUB is enabled and connected*) + IOTMQTT_CONNECTING, (*Client FUB is enabled and connecting*) + IOTMQTT_CONNECTION_LOST, (*Client FUB is enabled and lost the connection*) + IOTMQTT_CONNECTION_ERROR (*Client FUB is enabled and can't connect*) + ); + IotMqttPayloadType : STRUCT + pData : UDINT; (*Pointer to data buffer*) + Len : UDINT; (*Length of data buffer*) + END_STRUCT; + IotMqttSubscribeInfoType : STRUCT + NumberOfLostMessages : UDINT; (*Number of discarded messages because fifo was full*) + MessagesInQueue : UDINT; (*Number of waiting messages in the fifo*) + AvailableMessageSlots : UDINT; (*Number of available message slots in the fifo*) + TotalReceivedMessages : UDINT; (*Total number of received messages (including discarded messages)*) + END_STRUCT; + IotMqttPublishInfoType : STRUCT + MessagesPublished : UDINT; (*Number of sent messages*) + DeliveriesCompleted : UDINT; (*Number of acknowledged messages (delivery confirmed). Only used when QoS > 0*) + PublishErrorCounter : UDINT; (*Number of errors publishing*) + END_STRUCT; + IotMqttClientParType : STRUCT + ServerUri : STRING[255]; (*String containing broker's URI*) + Port : UINT := 1883; (*TCP port number used to connect to MQTT broker*) + ClientID : STRING[255]; (*String containing ClientID. Must be unique inside the broker*) + UserName : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the user name parameter*) + Password : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the password parameter*) + KeepAliveInterval : TIME := T#30s; (*The "keep alive" interval, defines the maximum time +that should pass without communication between the client and the server +The client will ensure that at least one message travels across the +network within each keep alive period. In the absence of a data-related +message during the time period, the client sends a very small MQTT +"ping" message, which the server will acknowledge. The keep alive +interval enables the client to detect when the server is no longer +available without having to wait for the long TCP/IP timeout. +Set to 0 if you do not want any keep alive processing.*) + LastWill : IotMqttClientParLastWillType; (*LastWill is enabled when the Topic Pointer is set*) + ConnectTimeout : TIME; (*The time interval to allow a connect to complete*) + MaxInFlight : UINT; (*This controls how many messages can be in-flight simultaneously.*) + MinRetryInterval : TIME; (*Minimum retry interval . Doubled on each failed retry*) + MaxRetryInterval : TIME; (*Maximum retry interval . The doubling stops here on failed retries.*) + TLS : IotMqttClientParTLSType; (*TLS parameters*) + PersistentData : BOOL; (*Enables persistentData on QOS > 0 items*) + AutomaticReconnect : BOOL := TRUE; (*Reconnect automatically in the case of a connection being lost*) + ConnectionType : IotMqttConnTypeEnum := IotMqtt_TCP; (*Determines if the connection will use standard TCP or WebSockets*) + CleanSession : BOOL; (*When cleansession is true, the state information is discarded at connect and disconnect. Setting cleansession to false keeps the state information*) + OfflinePublish : {REDUND_UNREPLICABLE} BOOL := FALSE; (*Whether to allow messages to be sent when the client is not connected.*) + OfflinePublishBuffer : UINT := 100; (*The maximum number of messages allowed to be buffered while not connected.*) + END_STRUCT; + IotMqttClientParTLSType : STRUCT + UseTLS : BOOL; (*Set to TRUE if TLS encryption is needed*) + CA : UDINT; (*Pointer to string. Name of the ca certificate stored in the CertificateStore*) + Cert : UDINT; (*Pointer to string. Name of the client certificate file stored in the CertificateStore*) + PrivateKey : UDINT; (*Pointer to string. Name of the private key file stored in the CertificateStore*) + PrivateKeyPassword : UDINT; (*Pointer to string. The password to load the client's privateKey if encrypted*) + EnabledCipherSuites : UDINT; (*Pointer to String.The list of cipher suites that the client will present to the server during the SSL handshake. For a +full explanation of the cipher list format, please see the OpenSSL on-line documentation: +http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT +If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding +those offering no encryption- will be considered. +This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).*) + EnableServerCertAuth : BOOL; (*True/False option to enable verification of the server certificate*) + END_STRUCT; + IotMqttClientParLastWillType : STRUCT + UseLastWill : BOOL; (*Makes use of last will and testament feature*) + Topic : UDINT; (*Pointer to NULL terminated string containing topic of the message*) + Buffer : UDINT; (*Pointer to NULL terminated string with the content of the message*) + BufferLength : UDINT; (*Bufferlenght to send*) + QoS : IotMqttQosEnum; (*QoS parameter (0 - 2)*) + Retain : BOOL; (*Is the message of type retain?*) + Payload : IotMqttPayloadType; (*Content payload, to be used (instead of Buffer) when sending binary data*) + END_STRUCT; + IotMqttClientInfoType : STRUCT + ConnectionState : IotMqttConnectionStateEnum; (*Unable to find host , Connecting , Connected , Connection Lost , Retrying *) + NumberActivePublishersFubs : UDINT; (*Number of active Publishers FUBs attached to this client*) + NumberActiveSubscribersFubs : UDINT; (*Number of active Subscribers FUBs attached to this client*) + PublishMessageCount : UDINT; (*Total number of messages published by this client since enabled*) + SubscribeMessageCount : UDINT; (*Total number of messages received by this client since enabled*) + PendingMessagesCount : UDINT; (*Total number of messages pendinf of delivery*) + END_STRUCT; + IotMqttReceivedMessageType : STRUCT + Topic : UDINT; (*Pointer to the topic of the message*) + TopicLen : UINT; (*Length of the topic*) + Buffer : UDINT; (*Pointer to the buffer with the content of the message*) + BufferLen : UDINT; (*Length of the message buffer*) + QoS : USINT; (*QoS parameter (0 - 2)*) + Retained : BOOL; (*Is the message of type retain?*) + END_STRUCT; + IoTMqttComIdentType : STRUCT + Internal : UDINT; + pThreadHandle : UDINT; + pThreadAttr : UDINT; + inst : UDINT; + END_STRUCT; + IotMqttConfigParametersType : STRUCT + LogLevel : IotMqttLogLevelEnum := IOTMQTT_LOG_LEVEL_ERROR; (*Log level*) + UseLogger : BOOL := 0; (*Use logger*) + LoggerName : STRING[8] := 'IotMqtt'; (*String containing the logger name. Only used if UseLogger is set*) + LoggerSize : UDINT := 2000000; (*Size of the logger in bytes*) + UseFile : BOOL := 1; (*Use file to output the log results*) + LogFileName : STRING[80] := 'IotMqttLog.txt'; (*String containing the file name. Only used if UseFile is set*) + LogFileDevice : STRING[80] := ''; (*String containing the filedevice name. Only used if UseFile is set*) + AppendTimestamp : BOOL := FALSE; (*A timestamp will be added to the filename so that it generates unique filenames. If disabled and the file already exists, it will be overwritten*) + OverwritteLogs : BOOL := TRUE; (*If set, it will delete previous logs if the name matches and no timestamp is added*) + PersistenceFileDevice : STRING[80] := 'IOTMQTT'; (*String containing the FileDevice for persistence files*) + END_STRUCT; + IotMqttGoogleIotJwtAlgorithmEnum : + ( + IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 + ); + IotMqttGoogleIotParametersType : STRUCT + ProjectID : STRING[80]; + Region : STRING[80]; + RegistryID : STRING[80]; + DeviceID : STRING[80]; + ExpirationPeriod : TIME; (*Token expiration period*) + Algorithm : IotMqttGoogleIotJwtAlgorithmEnum; + END_STRUCT; +END_TYPE diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/Binary.lby b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/Binary.lby new file mode 100644 index 0000000..45f703a --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/Binary.lby @@ -0,0 +1,20 @@ + + + + + Types.typ + Constants.var + IotMqtt.fun + + + + + + + + + + + + + \ No newline at end of file diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/Constants.var b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/Constants.var new file mode 100644 index 0000000..dce1395 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/Constants.var @@ -0,0 +1,43 @@ +(*Errors*) +VAR CONSTANT + IOTMQTT_ERR_NOT_FREE_HEAP : DINT := -10000; + IOTMQTT_ERR_NULL_HANDLE : DINT := -10001; + IOTMQTT_ERR_INVALID_HANDLE : DINT := -10002; + IOTMQTT_ERR_CA_CERTIFICATE : DINT := -10003; + IOTMQTT_ERR_CONNECTION_LOST : DINT := -10004; + IOTMQTT_ERR_CONNECTION_FAILED : DINT := -10005; + IOTMQTT_ERR_SUBSCRIBE : DINT := -10006; + IOTMQTT_ERR_FIFO_PUBLISH : DINT := -10007; + IOTMQTT_ERR_FIFO_SUBSCRIBE : DINT := -10008; + IOTMQTT_ERR_WRONG_PUBLISH_PAR : DINT := -10009; + IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR : DINT := -10010; + IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS : DINT := -10011; + IOTMQTT_ERR_WRONG_QUEUE_SIZE : DINT := -10012; + IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE : DINT := -10013; + IOTMQTT_ERR_CONN_REFUSED : DINT := -10014; + IOTMQTT_ERR_SENDING_TIMEDOUT : DINT := -10015; +END_VAR +(*Warnings*) +VAR CONSTANT + IOTMQTT_WRN_ALREADY_ALLOCATED : DINT := -20001; + IOTMQTT_WRN_ALREADY_FREED : DINT := -20002; + IOTMQTT_WRN_NO_MORE_MESSAGES : DINT := -20003; + IOTMQTT_WRN_FAILURE_SENDING : DINT := -20004; + IOTMQTT_WRN_FIFO_EMPTY : DINT := -20005; + IOTMQTT_WRN_CLIENT_DISABLED : DINT := -20006; + IOTMQTT_WRN_INVALID_DATA_RCVD : DINT := -20007; +END_VAR +(*OK*) +VAR CONSTANT + IOTMQTT_NO_ERR : DINT := 0; +END_VAR +(*Constants*) +VAR CONSTANT + MAX_SUBSCRIPTION_TOPICS : UINT := 50; + MAX_ENTRIES_RECEIVED_MESSAGES : UINT := 10; + MAX_ENTRIES_PUBLISH_MESSAGES : UINT := 500; + MAX_ENTRIES_SUBSCRIBE_OBJECTS : UINT := 50; + MAX_MESSAGE_TOKEN_TABLE : UINT := 1000; + MAX_PUBLISH_FUBS : UINT := 50; + MAX_SUBSCRIBE_FUBS : UINT := 50; +END_VAR diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/IotMqtt.fun b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/IotMqtt.fun new file mode 100644 index 0000000..dea6966 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/IotMqtt.fun @@ -0,0 +1,192 @@ + +{REDUND_ERROR} FUNCTION IotMqttConfig : INT (*Allows to configure library parameters. It only takes effect the first time it's called*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + ConfigParameters : REFERENCE TO IotMqttConfigParametersType; + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttClient + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + Connect : {REDUND_UNREPLICABLE} BOOL; (*If the FUB is enabled, attemps to connect with the remote MQTT broker*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Clears the current error*) + Parameters : {REDUND_UNREPLICABLE} IotMqttClientParType; (*Contains the client parameters*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and running*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttClientInfoType; (*Contains client information regarding the actual session*) + Connected : {REDUND_UNREPLICABLE} BOOL; (*TRUE if MQTT client is connected with the remote broker*) + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Send : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. Will send a new message each time is set high*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to data buffer*) + BufferLength : {REDUND_UNREPLICABLE} UDINT; (*Buffer length*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + END_VAR + VAR_OUTPUT + Busy : {REDUND_UNREPLICABLE} BOOL; (*Publishing*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Done : {REDUND_UNREPLICABLE} BOOL; (*Publish done*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Send : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _ErrorReset : {REDUND_UNREPLICABLE} BOOL; + _t0 : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Update : {REDUND_UNREPLICABLE} BOOL; (*Edfe sensitive. Will update the internal values for PvName, Mode, PublishMode and SamplingTime*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + PublishMode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; (*Which event or events will send the PV data?*) + SamplingTime : {REDUND_UNREPLICABLE} TIME; (*Sampling rate used for saving new values (used for time-based send mode). On a change, the new value is only applied on a rising edge of Update*) + Trigger : {REDUND_UNREPLICABLE} BOOL; (*Trigger (used for the recording mode that works with a trigger).*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*Working in serialization + sending*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Publish : {REDUND_UNREPLICABLE} IotMqttPublish; + _Serializer : {REDUND_UNREPLICABLE} UDINT; + _Processing : {REDUND_UNREPLICABLE} BOOL; + _prevPV : {REDUND_UNREPLICABLE} UDINT; + _trig : {REDUND_UNREPLICABLE} BOOL; + _addr : {REDUND_UNREPLICABLE} UDINT; + _datalen : {REDUND_UNREPLICABLE} UDINT; + _enable : {REDUND_UNREPLICABLE} BOOL; + _pvname : {REDUND_UNREPLICABLE} UDINT; + _publishmode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; + _mode : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; + _update : {REDUND_UNREPLICABLE} BOOL; + _samplingtime : {REDUND_UNREPLICABLE} TIME; + _t0 : {REDUND_UNREPLICABLE} TIME; + _pubCmd : {REDUND_UNREPLICABLE} BOOL; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB. Subscription will take place at enable of the FUB, if the associated IotMqttClient FUB is enabled and connected.*) + Read : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. When activaded it will deliver one message from the internal FIFO*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + SubscriptionQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + RecievedTopicSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the received topic buffer*) + QueueSize : {REDUND_UNREPLICABLE} USINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to memory area where the content of the read messages will be stored*) + BufferSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the memory area where the content of the read messages will be stored*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The read message from the FIFO has the "Retain" flag*) + ReceivedQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The read message from the FIFO has this QoS*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Subscribed : {REDUND_UNREPLICABLE} BOOL; (*Subscription completed succesfully*) + MessageRetrieved : {REDUND_UNREPLICABLE} BOOL; (*Read operation completed succesfully*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + NewDataValid : {REDUND_UNREPLICABLE} BOOL; (*Is TRUE if new data was received with the last FB call*) + DataSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the Buffer array used in bytes*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Enable : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _Internal : {REDUND_UNREPLICABLE} UDINT; + _FifoHandle : {REDUND_UNREPLICABLE} UDINT; + _Read : {REDUND_UNREPLICABLE} BOOL; + _Subscribing : {REDUND_UNREPLICABLE} BOOL; + _FifoLock : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + QueueSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The received message has the "Retain" flag*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + UpdateNotification : {REDUND_UNREPLICABLE} BOOL; (*registered PV contains new values. This is automatically reset after one cycle.*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Receive : {REDUND_UNREPLICABLE} IotMqttSubscribe; + _Parser : {REDUND_UNREPLICABLE} UDINT; + _RecvBuffer : {REDUND_UNREPLICABLE} UDINT; + _ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + _Step : {REDUND_UNREPLICABLE} USINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_ERROR} FUNCTION AzureGenerateDeviceCredentials : INT (*Given an AzureIoT Hub device connection string, and the "TimeToLive" parameter, will populate the needed parameters for connecting it*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + pConnectionString : UDINT; (*Pointer to string with the connection string*) + TimeToLive : USINT; (*Time in hours that the password will be valid*) + pParameters : UDINT; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + PublishTelemetryTopic : UDINT; (*Pointer to string to store the publish topic*) + SizeofPublishTelemetryTopic : UDINT; (*Size of PublishTelemetryTopic variable*) + SubscribeTelemetryTopic : UDINT; (*Pointer to string to store the subscribe topic*) + SizeofSubscribeTelemetryTopic : UDINT; (*Size of SubscribeTelemetryTopic variable*) + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK GoogleIotCredentials (*Get JWT token for MQTT connection*) + VAR_INPUT + Execute : {REDUND_UNREPLICABLE} BOOL; + pIotMqttGoogleIotParameters : REFERENCE TO IotMqttGoogleIotParametersType; + pJWT : {REDUND_UNREPLICABLE} UDINT; (*Pointer to string. It will be filled with JWT*) + SizeOfJWT : {REDUND_UNREPLICABLE} UDINT; (*Size of destination JWT string*) + pIotMqttClientParameters : REFERENCE TO IotMqttClientParType; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + END_VAR + VAR_OUTPUT + Error : {REDUND_UNREPLICABLE} BOOL; + Done : {REDUND_UNREPLICABLE} BOOL; + Busy : {REDUND_UNREPLICABLE} BOOL; + END_VAR + VAR + _Execute : {REDUND_UNREPLICABLE} BOOL; + _hTask : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/Arm/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/Arm/IotMqtt.br new file mode 100644 index 0000000..df419d5 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/Arm/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/Arm/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/Arm/libIotMqtt.a new file mode 100644 index 0000000..4425429 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/Arm/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/IotMqtt.br new file mode 100644 index 0000000..5ff5cea Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/IotMqtt.h b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/IotMqtt.h new file mode 100644 index 0000000..daad6ca --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/IotMqtt.h @@ -0,0 +1,474 @@ +/* Automation Studio generated header file */ +/* Do not edit ! */ +/* IotMqtt 4.63.0 */ + +#ifndef _IOTMQTT_ +#define _IOTMQTT_ +#ifdef __cplusplus +extern "C" +{ +#endif +#ifndef _IotMqtt_VERSION +#define _IotMqtt_VERSION 4.63.0 +#endif + +#include + +#ifndef _BUR_PUBLIC +#define _BUR_PUBLIC +#endif +#ifdef _SG3 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif +#ifdef _SG4 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif +#ifdef _SGC + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif + + +/* Constants */ +#ifdef _REPLACE_CONST + #define IOTMQTT_ERR_NOT_FREE_HEAP (-10000) + #define IOTMQTT_ERR_NULL_HANDLE (-10001) + #define IOTMQTT_ERR_INVALID_HANDLE (-10002) + #define IOTMQTT_ERR_CA_CERTIFICATE (-10003) + #define IOTMQTT_ERR_CONNECTION_LOST (-10004) + #define IOTMQTT_ERR_CONNECTION_FAILED (-10005) + #define IOTMQTT_ERR_SUBSCRIBE (-10006) + #define IOTMQTT_ERR_FIFO_PUBLISH (-10007) + #define IOTMQTT_ERR_FIFO_SUBSCRIBE (-10008) + #define IOTMQTT_ERR_WRONG_PUBLISH_PAR (-10009) + #define IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR (-10010) + #define IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS (-10011) + #define IOTMQTT_ERR_WRONG_QUEUE_SIZE (-10012) + #define IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE (-10013) + #define IOTMQTT_ERR_CONN_REFUSED (-10014) + #define IOTMQTT_ERR_SENDING_TIMEDOUT (-10015) + #define IOTMQTT_WRN_ALREADY_ALLOCATED (-20001) + #define IOTMQTT_WRN_ALREADY_FREED (-20002) + #define IOTMQTT_WRN_NO_MORE_MESSAGES (-20003) + #define IOTMQTT_WRN_FAILURE_SENDING (-20004) + #define IOTMQTT_WRN_FIFO_EMPTY (-20005) + #define IOTMQTT_WRN_CLIENT_DISABLED (-20006) + #define IOTMQTT_WRN_INVALID_DATA_RCVD (-20007) + #define IOTMQTT_NO_ERR 0 + #define MAX_SUBSCRIPTION_TOPICS 50U + #define MAX_ENTRIES_RECEIVED_MESSAGES 10U + #define MAX_ENTRIES_PUBLISH_MESSAGES 500U + #define MAX_ENTRIES_SUBSCRIBE_OBJECTS 50U + #define MAX_MESSAGE_TOKEN_TABLE 1000U + #define MAX_PUBLISH_FUBS 50U + #define MAX_SUBSCRIBE_FUBS 50U +#else + _GLOBAL_CONST signed long IOTMQTT_ERR_NOT_FREE_HEAP; + _GLOBAL_CONST signed long IOTMQTT_ERR_NULL_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_INVALID_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CA_CERTIFICATE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_LOST; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_FAILED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_PUBLISH; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_PUBLISH_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_QUEUE_SIZE; + _GLOBAL_CONST signed long IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONN_REFUSED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SENDING_TIMEDOUT; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_ALLOCATED; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_FREED; + _GLOBAL_CONST signed long IOTMQTT_WRN_NO_MORE_MESSAGES; + _GLOBAL_CONST signed long IOTMQTT_WRN_FAILURE_SENDING; + _GLOBAL_CONST signed long IOTMQTT_WRN_FIFO_EMPTY; + _GLOBAL_CONST signed long IOTMQTT_WRN_CLIENT_DISABLED; + _GLOBAL_CONST signed long IOTMQTT_WRN_INVALID_DATA_RCVD; + _GLOBAL_CONST signed long IOTMQTT_NO_ERR; + _GLOBAL_CONST unsigned short MAX_SUBSCRIPTION_TOPICS; + _GLOBAL_CONST unsigned short MAX_ENTRIES_RECEIVED_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_PUBLISH_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_SUBSCRIBE_OBJECTS; + _GLOBAL_CONST unsigned short MAX_MESSAGE_TOKEN_TABLE; + _GLOBAL_CONST unsigned short MAX_PUBLISH_FUBS; + _GLOBAL_CONST unsigned short MAX_SUBSCRIBE_FUBS; +#endif + + + + +/* Datatypes and datatypes of function blocks */ +typedef enum IotMqttConnTypeEnum +{ IotMqtt_TCP, + IotMqtt_WS +} IotMqttConnTypeEnum; + +typedef enum IotMqttQosEnum +{ IotMqtt_QoS0 = 0, + IotMqtt_QoS1 = 1, + IotMqtt_QoS2 = 2 +} IotMqttQosEnum; + +typedef enum IotMqttPublishModeEnum +{ IOTMQTT_PUB_MODE_TIME, + IOTMQTT_PUB_MODE_TRIGGER, + IOTMQTT_PUB_MODE_VALUE, + IOTMQTT_PUB_MODE_TIME_TRIGGER, + IOTMQTT_PUB_MODE_TIME_VALUE, + IOTMQTT_PUB_MODE_TRIGGER_VALUE, + IOTMQTT_PUB_MODE_TIME_TRG_VALUE +} IotMqttPublishModeEnum; + +typedef enum IotMqttLogLevelEnum +{ IOTMQTT_LOG_LEVEL_ERROR, + IOTMQTT_LOG_LEVEL_PROTOCOL, + IOTMQTT_LOG_LEVEL_MAXIMUM +} IotMqttLogLevelEnum; + +typedef enum IotMqttDataFormatEnum +{ IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON +} IotMqttDataFormatEnum; + +typedef enum IotMqttConnectionStateEnum +{ IOTMQTT_DISABLED, + IOTMQTT_DISCONNECTED, + IOTMQTT_DISCONNECTING, + IOTMQTT_CONNECTED, + IOTMQTT_CONNECTING, + IOTMQTT_CONNECTION_LOST, + IOTMQTT_CONNECTION_ERROR +} IotMqttConnectionStateEnum; + +typedef enum IotMqttGoogleIotJwtAlgorithmEnum +{ IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 +} IotMqttGoogleIotJwtAlgorithmEnum; + +typedef struct IotMqttPayloadType +{ unsigned long pData; + unsigned long Len; +} IotMqttPayloadType; + +typedef struct IotMqttSubscribeInfoType +{ unsigned long NumberOfLostMessages; + unsigned long MessagesInQueue; + unsigned long AvailableMessageSlots; + unsigned long TotalReceivedMessages; +} IotMqttSubscribeInfoType; + +typedef struct IotMqttPublishInfoType +{ unsigned long MessagesPublished; + unsigned long DeliveriesCompleted; + unsigned long PublishErrorCounter; +} IotMqttPublishInfoType; + +typedef struct IotMqttClientParLastWillType +{ plcbit UseLastWill; + unsigned long Topic; + unsigned long Buffer; + unsigned long BufferLength; + enum IotMqttQosEnum QoS; + plcbit Retain; + struct IotMqttPayloadType Payload; +} IotMqttClientParLastWillType; + +typedef struct IotMqttClientParTLSType +{ plcbit UseTLS; + unsigned long CA; + unsigned long Cert; + unsigned long PrivateKey; + unsigned long PrivateKeyPassword; + unsigned long EnabledCipherSuites; + plcbit EnableServerCertAuth; +} IotMqttClientParTLSType; + +typedef struct IotMqttClientParType +{ plcstring ServerUri[256]; + unsigned short Port; + plcstring ClientID[256]; + plcstring UserName[256]; + plcstring Password[256]; + plctime KeepAliveInterval; + struct IotMqttClientParLastWillType LastWill; + plctime ConnectTimeout; + unsigned short MaxInFlight; + plctime MinRetryInterval; + plctime MaxRetryInterval; + struct IotMqttClientParTLSType TLS; + plcbit PersistentData; + plcbit AutomaticReconnect; + enum IotMqttConnTypeEnum ConnectionType; + plcbit CleanSession; + plcbit OfflinePublish; + unsigned short OfflinePublishBuffer; +} IotMqttClientParType; + +typedef struct IotMqttClientInfoType +{ enum IotMqttConnectionStateEnum ConnectionState; + unsigned long NumberActivePublishersFubs; + unsigned long NumberActiveSubscribersFubs; + unsigned long PublishMessageCount; + unsigned long SubscribeMessageCount; + unsigned long PendingMessagesCount; +} IotMqttClientInfoType; + +typedef struct IotMqttReceivedMessageType +{ unsigned long Topic; + unsigned short TopicLen; + unsigned long Buffer; + unsigned long BufferLen; + unsigned char QoS; + plcbit Retained; +} IotMqttReceivedMessageType; + +typedef struct IoTMqttComIdentType +{ unsigned long Internal; + unsigned long pThreadHandle; + unsigned long pThreadAttr; + unsigned long inst; +} IoTMqttComIdentType; + +typedef struct IotMqttConfigParametersType +{ enum IotMqttLogLevelEnum LogLevel; + plcbit UseLogger; + plcstring LoggerName[9]; + unsigned long LoggerSize; + plcbit UseFile; + plcstring LogFileName[81]; + plcstring LogFileDevice[81]; + plcbit AppendTimestamp; + plcbit OverwritteLogs; + plcstring PersistenceFileDevice[81]; +} IotMqttConfigParametersType; + +typedef struct IotMqttGoogleIotParametersType +{ plcstring ProjectID[81]; + plcstring Region[81]; + plcstring RegistryID[81]; + plcstring DeviceID[81]; + plctime ExpirationPeriod; + enum IotMqttGoogleIotJwtAlgorithmEnum Algorithm; +} IotMqttGoogleIotParametersType; + +typedef struct IotMqttClient +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + struct IotMqttClientParType Parameters; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttClientInfoType Info; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Connect; + plcbit ErrorReset; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Error; + plcbit Connected; +} IotMqttClient_typ; + +typedef struct IotMqttPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + plctime SendTimeout; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long Buffer; + unsigned long BufferLength; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + unsigned long _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Send; + plcbit Retained; + /* VAR_OUTPUT (digital) */ + plcbit Busy; + plcbit Active; + plcbit Done; + plcbit Error; + /* VAR (digital) */ + plcbit _Send; + plcbit _Active; + plcbit _ErrorReset; +} IotMqttPublish_typ; + +typedef struct IotMqttRegParPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum QoS; + plctime SendTimeout; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + enum IotMqttPublishModeEnum PublishMode; + plctime SamplingTime; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + struct IotMqttPublish _Publish; + unsigned long _Serializer; + unsigned long _prevPV; + unsigned long _addr; + unsigned long _datalen; + unsigned long _pvname; + enum IotMqttPublishModeEnum _publishmode; + enum IotMqttDataFormatEnum _mode; + plctime _samplingtime; + plctime _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Update; + plcbit Retained; + plcbit Trigger; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Busy; + plcbit Error; + /* VAR (digital) */ + plcbit _Processing; + plcbit _trig; + plcbit _enable; + plcbit _update; + plcbit _pubCmd; +} IotMqttRegParPublish_typ; + +typedef struct IotMqttSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum SubscriptionQoS; + unsigned long RecievedTopic; + unsigned long RecievedTopicSize; + unsigned char QueueSize; + unsigned long Buffer; + unsigned long BufferSize; + /* VAR_OUTPUT (analog) */ + enum IotMqttQosEnum ReceivedQoS; + signed long StatusID; + unsigned long DataSize; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + unsigned long _Internal; + unsigned long _FifoHandle; + unsigned long _FifoLock; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Read; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Subscribed; + plcbit MessageRetrieved; + plcbit Error; + plcbit Busy; + plcbit NewDataValid; + /* VAR (digital) */ + plcbit _Enable; + plcbit _Active; + plcbit _Read; + plcbit _Subscribing; +} IotMqttSubscribe_typ; + +typedef struct IotMqttRegParSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long RecievedTopic; + unsigned long QueueSize; + unsigned long ReceiveBufferSize; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + struct IotMqttSubscribe _Receive; + unsigned long _Parser; + unsigned long _RecvBuffer; + unsigned long _ReceiveBufferSize; + unsigned char _Step; + /* VAR_INPUT (digital) */ + plcbit Enable; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Busy; + plcbit Error; + plcbit UpdateNotification; +} IotMqttRegParSubscribe_typ; + +typedef struct GoogleIotCredentials +{ + /* VAR_INPUT (analog) */ + struct IotMqttGoogleIotParametersType* pIotMqttGoogleIotParameters; + unsigned long pJWT; + unsigned long SizeOfJWT; + struct IotMqttClientParType* pIotMqttClientParameters; + /* VAR (analog) */ + unsigned long _hTask; + /* VAR_INPUT (digital) */ + plcbit Execute; + /* VAR_OUTPUT (digital) */ + plcbit Error; + plcbit Done; + plcbit Busy; + /* VAR (digital) */ + plcbit _Execute; +} GoogleIotCredentials_typ; + + + +/* Prototyping of functions and function blocks */ +_BUR_PUBLIC void IotMqttClient(struct IotMqttClient* inst); +_BUR_PUBLIC void IotMqttPublish(struct IotMqttPublish* inst); +_BUR_PUBLIC void IotMqttRegParPublish(struct IotMqttRegParPublish* inst); +_BUR_PUBLIC void IotMqttSubscribe(struct IotMqttSubscribe* inst); +_BUR_PUBLIC void IotMqttRegParSubscribe(struct IotMqttRegParSubscribe* inst); +_BUR_PUBLIC void GoogleIotCredentials(struct GoogleIotCredentials* inst); +_BUR_PUBLIC signed short IotMqttConfig(struct IotMqttConfigParametersType** ConfigParameters); +_BUR_PUBLIC signed short AzureGenerateDeviceCredentials(unsigned long pConnectionString, unsigned char TimeToLive, unsigned long pParameters, unsigned long PublishTelemetryTopic, unsigned long SizeofPublishTelemetryTopic, unsigned long SubscribeTelemetryTopic, unsigned long SizeofSubscribeTelemetryTopic); + + +#ifdef __cplusplus +}; +#endif +#endif /* _IOTMQTT_ */ + diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/libIotMqtt.a new file mode 100644 index 0000000..2217229 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/SG4/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/Types.typ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/Types.typ new file mode 100644 index 0000000..42ac63c --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.63.0/Types.typ @@ -0,0 +1,159 @@ + +TYPE + IotMqttConnTypeEnum : + ( + IotMqtt_TCP, (*Use standard TCP connection*) + IotMqtt_WS (*Use connection over websockets*) + ); + IotMqttQosEnum : + ( (*The quality of service (QoS) assigned to the message. +*) + IotMqtt_QoS0 := 0, (*Fire and forget - the message may not be delivered*) + IotMqtt_QoS1 := 1, (*At least once - the message will be delivered, but may be delivered more than once in some circumstances*) + IotMqtt_QoS2 := 2 (*Once and one only - the message will be delivered exactly once.*) + ); + IotMqttPublishModeEnum : + ( + IOTMQTT_PUB_MODE_TIME, (*New data is published on a time basis. *) + IOTMQTT_PUB_MODE_TRIGGER, (*New data is published after a trigger. *) + IOTMQTT_PUB_MODE_VALUE, (*New data from the PVs is published after the value of the PV is changed. *) + IOTMQTT_PUB_MODE_TIME_TRIGGER, (*New data is published at a certain time or after a trigger. *) + IOTMQTT_PUB_MODE_TIME_VALUE, (*New data is published at a certain time or after the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TRIGGER_VALUE, (*New data is published after a trigger or the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TIME_TRG_VALUE (*New data is published at a certain time, after the value of the registered PV changes or after a trigger. *) + ); + IotMqttLogLevelEnum : + ( + IOTMQTT_LOG_LEVEL_ERROR, (*Just errors are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_PROTOCOL, (*MQTT protocol operations are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_MAXIMUM (*Diagnosis messages are written to the log file or logger*) + ); + IotMqttDataFormatEnum : + ( + IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON + ); + IotMqttConnectionStateEnum : + ( + IOTMQTT_DISABLED, (*Client FUB is disabled*) + IOTMQTT_DISCONNECTED, (*Client FUB is enabled and disconnected*) + IOTMQTT_DISCONNECTING, (*Client FUB is enabled and disconnecting*) + IOTMQTT_CONNECTED, (*Client FUB is enabled and connected*) + IOTMQTT_CONNECTING, (*Client FUB is enabled and connecting*) + IOTMQTT_CONNECTION_LOST, (*Client FUB is enabled and lost the connection*) + IOTMQTT_CONNECTION_ERROR (*Client FUB is enabled and can't connect*) + ); + IotMqttPayloadType : STRUCT + pData : UDINT; (*Pointer to data buffer*) + Len : UDINT; (*Length of data buffer*) + END_STRUCT; + IotMqttSubscribeInfoType : STRUCT + NumberOfLostMessages : UDINT; (*Number of discarded messages because fifo was full*) + MessagesInQueue : UDINT; (*Number of waiting messages in the fifo*) + AvailableMessageSlots : UDINT; (*Number of available message slots in the fifo*) + TotalReceivedMessages : UDINT; (*Total number of received messages (including discarded messages)*) + END_STRUCT; + IotMqttPublishInfoType : STRUCT + MessagesPublished : UDINT; (*Number of sent messages*) + DeliveriesCompleted : UDINT; (*Number of acknowledged messages (delivery confirmed). Only used when QoS > 0*) + PublishErrorCounter : UDINT; (*Number of errors publishing*) + END_STRUCT; + IotMqttClientParType : STRUCT + ServerUri : STRING[255]; (*String containing broker's URI*) + Port : UINT := 1883; (*TCP port number used to connect to MQTT broker*) + ClientID : STRING[255]; (*String containing ClientID. Must be unique inside the broker*) + UserName : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the user name parameter*) + Password : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the password parameter*) + KeepAliveInterval : TIME := T#30s; (*The "keep alive" interval, defines the maximum time +that should pass without communication between the client and the server +The client will ensure that at least one message travels across the +network within each keep alive period. In the absence of a data-related +message during the time period, the client sends a very small MQTT +"ping" message, which the server will acknowledge. The keep alive +interval enables the client to detect when the server is no longer +available without having to wait for the long TCP/IP timeout. +Set to 0 if you do not want any keep alive processing.*) + LastWill : IotMqttClientParLastWillType; (*LastWill is enabled when the Topic Pointer is set*) + ConnectTimeout : TIME; (*The time interval to allow a connect to complete*) + MaxInFlight : UINT; (*This controls how many messages can be in-flight simultaneously.*) + MinRetryInterval : TIME; (*Minimum retry interval . Doubled on each failed retry*) + MaxRetryInterval : TIME; (*Maximum retry interval . The doubling stops here on failed retries.*) + TLS : IotMqttClientParTLSType; (*TLS parameters*) + PersistentData : BOOL; (*Enables persistentData on QOS > 0 items*) + AutomaticReconnect : BOOL := TRUE; (*Reconnect automatically in the case of a connection being lost*) + ConnectionType : IotMqttConnTypeEnum := IotMqtt_TCP; (*Determines if the connection will use standard TCP or WebSockets*) + CleanSession : BOOL; (*When cleansession is true, the state information is discarded at connect and disconnect. Setting cleansession to false keeps the state information*) + OfflinePublish : {REDUND_UNREPLICABLE} BOOL := FALSE; (*Whether to allow messages to be sent when the client is not connected.*) + OfflinePublishBuffer : UINT := 100; (*The maximum number of messages allowed to be buffered while not connected.*) + END_STRUCT; + IotMqttClientParTLSType : STRUCT + UseTLS : BOOL; (*Set to TRUE if TLS encryption is needed*) + CA : UDINT; (*Pointer to string. Name of the ca certificate stored in the CertificateStore*) + Cert : UDINT; (*Pointer to string. Name of the client certificate file stored in the CertificateStore*) + PrivateKey : UDINT; (*Pointer to string. Name of the private key file stored in the CertificateStore*) + PrivateKeyPassword : UDINT; (*Pointer to string. The password to load the client's privateKey if encrypted*) + EnabledCipherSuites : UDINT; (*Pointer to String.The list of cipher suites that the client will present to the server during the SSL handshake. For a +full explanation of the cipher list format, please see the OpenSSL on-line documentation: +http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT +If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding +those offering no encryption- will be considered. +This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).*) + EnableServerCertAuth : BOOL; (*True/False option to enable verification of the server certificate*) + END_STRUCT; + IotMqttClientParLastWillType : STRUCT + UseLastWill : BOOL; (*Makes use of last will and testament feature*) + Topic : UDINT; (*Pointer to NULL terminated string containing topic of the message*) + Buffer : UDINT; (*Pointer to NULL terminated string with the content of the message*) + BufferLength : UDINT; (*Bufferlenght to send*) + QoS : IotMqttQosEnum; (*QoS parameter (0 - 2)*) + Retain : BOOL; (*Is the message of type retain?*) + Payload : IotMqttPayloadType; (*Content payload, to be used (instead of Buffer) when sending binary data*) + END_STRUCT; + IotMqttClientInfoType : STRUCT + ConnectionState : IotMqttConnectionStateEnum; (*Unable to find host , Connecting , Connected , Connection Lost , Retrying *) + NumberActivePublishersFubs : UDINT; (*Number of active Publishers FUBs attached to this client*) + NumberActiveSubscribersFubs : UDINT; (*Number of active Subscribers FUBs attached to this client*) + PublishMessageCount : UDINT; (*Total number of messages published by this client since enabled*) + SubscribeMessageCount : UDINT; (*Total number of messages received by this client since enabled*) + PendingMessagesCount : UDINT; (*Total number of messages pendinf of delivery*) + END_STRUCT; + IotMqttReceivedMessageType : STRUCT + Topic : UDINT; (*Pointer to the topic of the message*) + TopicLen : UINT; (*Length of the topic*) + Buffer : UDINT; (*Pointer to the buffer with the content of the message*) + BufferLen : UDINT; (*Length of the message buffer*) + QoS : USINT; (*QoS parameter (0 - 2)*) + Retained : BOOL; (*Is the message of type retain?*) + END_STRUCT; + IoTMqttComIdentType : STRUCT + Internal : UDINT; + pThreadHandle : UDINT; + pThreadAttr : UDINT; + inst : UDINT; + END_STRUCT; + IotMqttConfigParametersType : STRUCT + LogLevel : IotMqttLogLevelEnum := IOTMQTT_LOG_LEVEL_ERROR; (*Log level*) + UseLogger : BOOL := 0; (*Use logger*) + LoggerName : STRING[8] := 'IotMqtt'; (*String containing the logger name. Only used if UseLogger is set*) + LoggerSize : UDINT := 2000000; (*Size of the logger in bytes*) + UseFile : BOOL := 1; (*Use file to output the log results*) + LogFileName : STRING[80] := 'IotMqttLog.txt'; (*String containing the file name. Only used if UseFile is set*) + LogFileDevice : STRING[80] := ''; (*String containing the filedevice name. Only used if UseFile is set*) + AppendTimestamp : BOOL := FALSE; (*A timestamp will be added to the filename so that it generates unique filenames. If disabled and the file already exists, it will be overwritten*) + OverwritteLogs : BOOL := TRUE; (*If set, it will delete previous logs if the name matches and no timestamp is added*) + PersistenceFileDevice : STRING[80] := 'IOTMQTT'; (*String containing the FileDevice for persistence files*) + END_STRUCT; + IotMqttGoogleIotJwtAlgorithmEnum : + ( + IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 + ); + IotMqttGoogleIotParametersType : STRUCT + ProjectID : STRING[80]; + Region : STRING[80]; + RegistryID : STRING[80]; + DeviceID : STRING[80]; + ExpirationPeriod : TIME; (*Token expiration period*) + Algorithm : IotMqttGoogleIotJwtAlgorithmEnum; + END_STRUCT; +END_TYPE diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/Binary.lby b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/Binary.lby new file mode 100644 index 0000000..b98bf6c --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/Binary.lby @@ -0,0 +1,20 @@ + + + + + Types.typ + Constants.var + IotMqtt.fun + + + + + + + + + + + + + \ No newline at end of file diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/Constants.var b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/Constants.var new file mode 100644 index 0000000..dce1395 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/Constants.var @@ -0,0 +1,43 @@ +(*Errors*) +VAR CONSTANT + IOTMQTT_ERR_NOT_FREE_HEAP : DINT := -10000; + IOTMQTT_ERR_NULL_HANDLE : DINT := -10001; + IOTMQTT_ERR_INVALID_HANDLE : DINT := -10002; + IOTMQTT_ERR_CA_CERTIFICATE : DINT := -10003; + IOTMQTT_ERR_CONNECTION_LOST : DINT := -10004; + IOTMQTT_ERR_CONNECTION_FAILED : DINT := -10005; + IOTMQTT_ERR_SUBSCRIBE : DINT := -10006; + IOTMQTT_ERR_FIFO_PUBLISH : DINT := -10007; + IOTMQTT_ERR_FIFO_SUBSCRIBE : DINT := -10008; + IOTMQTT_ERR_WRONG_PUBLISH_PAR : DINT := -10009; + IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR : DINT := -10010; + IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS : DINT := -10011; + IOTMQTT_ERR_WRONG_QUEUE_SIZE : DINT := -10012; + IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE : DINT := -10013; + IOTMQTT_ERR_CONN_REFUSED : DINT := -10014; + IOTMQTT_ERR_SENDING_TIMEDOUT : DINT := -10015; +END_VAR +(*Warnings*) +VAR CONSTANT + IOTMQTT_WRN_ALREADY_ALLOCATED : DINT := -20001; + IOTMQTT_WRN_ALREADY_FREED : DINT := -20002; + IOTMQTT_WRN_NO_MORE_MESSAGES : DINT := -20003; + IOTMQTT_WRN_FAILURE_SENDING : DINT := -20004; + IOTMQTT_WRN_FIFO_EMPTY : DINT := -20005; + IOTMQTT_WRN_CLIENT_DISABLED : DINT := -20006; + IOTMQTT_WRN_INVALID_DATA_RCVD : DINT := -20007; +END_VAR +(*OK*) +VAR CONSTANT + IOTMQTT_NO_ERR : DINT := 0; +END_VAR +(*Constants*) +VAR CONSTANT + MAX_SUBSCRIPTION_TOPICS : UINT := 50; + MAX_ENTRIES_RECEIVED_MESSAGES : UINT := 10; + MAX_ENTRIES_PUBLISH_MESSAGES : UINT := 500; + MAX_ENTRIES_SUBSCRIBE_OBJECTS : UINT := 50; + MAX_MESSAGE_TOKEN_TABLE : UINT := 1000; + MAX_PUBLISH_FUBS : UINT := 50; + MAX_SUBSCRIBE_FUBS : UINT := 50; +END_VAR diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/IotMqtt.fun b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/IotMqtt.fun new file mode 100644 index 0000000..dea6966 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/IotMqtt.fun @@ -0,0 +1,192 @@ + +{REDUND_ERROR} FUNCTION IotMqttConfig : INT (*Allows to configure library parameters. It only takes effect the first time it's called*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + ConfigParameters : REFERENCE TO IotMqttConfigParametersType; + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttClient + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + Connect : {REDUND_UNREPLICABLE} BOOL; (*If the FUB is enabled, attemps to connect with the remote MQTT broker*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Clears the current error*) + Parameters : {REDUND_UNREPLICABLE} IotMqttClientParType; (*Contains the client parameters*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and running*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttClientInfoType; (*Contains client information regarding the actual session*) + Connected : {REDUND_UNREPLICABLE} BOOL; (*TRUE if MQTT client is connected with the remote broker*) + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Send : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. Will send a new message each time is set high*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to data buffer*) + BufferLength : {REDUND_UNREPLICABLE} UDINT; (*Buffer length*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + END_VAR + VAR_OUTPUT + Busy : {REDUND_UNREPLICABLE} BOOL; (*Publishing*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Done : {REDUND_UNREPLICABLE} BOOL; (*Publish done*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Send : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _ErrorReset : {REDUND_UNREPLICABLE} BOOL; + _t0 : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Update : {REDUND_UNREPLICABLE} BOOL; (*Edfe sensitive. Will update the internal values for PvName, Mode, PublishMode and SamplingTime*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + PublishMode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; (*Which event or events will send the PV data?*) + SamplingTime : {REDUND_UNREPLICABLE} TIME; (*Sampling rate used for saving new values (used for time-based send mode). On a change, the new value is only applied on a rising edge of Update*) + Trigger : {REDUND_UNREPLICABLE} BOOL; (*Trigger (used for the recording mode that works with a trigger).*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*Working in serialization + sending*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Publish : {REDUND_UNREPLICABLE} IotMqttPublish; + _Serializer : {REDUND_UNREPLICABLE} UDINT; + _Processing : {REDUND_UNREPLICABLE} BOOL; + _prevPV : {REDUND_UNREPLICABLE} UDINT; + _trig : {REDUND_UNREPLICABLE} BOOL; + _addr : {REDUND_UNREPLICABLE} UDINT; + _datalen : {REDUND_UNREPLICABLE} UDINT; + _enable : {REDUND_UNREPLICABLE} BOOL; + _pvname : {REDUND_UNREPLICABLE} UDINT; + _publishmode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; + _mode : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; + _update : {REDUND_UNREPLICABLE} BOOL; + _samplingtime : {REDUND_UNREPLICABLE} TIME; + _t0 : {REDUND_UNREPLICABLE} TIME; + _pubCmd : {REDUND_UNREPLICABLE} BOOL; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB. Subscription will take place at enable of the FUB, if the associated IotMqttClient FUB is enabled and connected.*) + Read : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. When activaded it will deliver one message from the internal FIFO*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + SubscriptionQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + RecievedTopicSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the received topic buffer*) + QueueSize : {REDUND_UNREPLICABLE} USINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to memory area where the content of the read messages will be stored*) + BufferSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the memory area where the content of the read messages will be stored*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The read message from the FIFO has the "Retain" flag*) + ReceivedQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The read message from the FIFO has this QoS*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Subscribed : {REDUND_UNREPLICABLE} BOOL; (*Subscription completed succesfully*) + MessageRetrieved : {REDUND_UNREPLICABLE} BOOL; (*Read operation completed succesfully*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + NewDataValid : {REDUND_UNREPLICABLE} BOOL; (*Is TRUE if new data was received with the last FB call*) + DataSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the Buffer array used in bytes*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Enable : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _Internal : {REDUND_UNREPLICABLE} UDINT; + _FifoHandle : {REDUND_UNREPLICABLE} UDINT; + _Read : {REDUND_UNREPLICABLE} BOOL; + _Subscribing : {REDUND_UNREPLICABLE} BOOL; + _FifoLock : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + QueueSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The received message has the "Retain" flag*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + UpdateNotification : {REDUND_UNREPLICABLE} BOOL; (*registered PV contains new values. This is automatically reset after one cycle.*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Receive : {REDUND_UNREPLICABLE} IotMqttSubscribe; + _Parser : {REDUND_UNREPLICABLE} UDINT; + _RecvBuffer : {REDUND_UNREPLICABLE} UDINT; + _ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + _Step : {REDUND_UNREPLICABLE} USINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_ERROR} FUNCTION AzureGenerateDeviceCredentials : INT (*Given an AzureIoT Hub device connection string, and the "TimeToLive" parameter, will populate the needed parameters for connecting it*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + pConnectionString : UDINT; (*Pointer to string with the connection string*) + TimeToLive : USINT; (*Time in hours that the password will be valid*) + pParameters : UDINT; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + PublishTelemetryTopic : UDINT; (*Pointer to string to store the publish topic*) + SizeofPublishTelemetryTopic : UDINT; (*Size of PublishTelemetryTopic variable*) + SubscribeTelemetryTopic : UDINT; (*Pointer to string to store the subscribe topic*) + SizeofSubscribeTelemetryTopic : UDINT; (*Size of SubscribeTelemetryTopic variable*) + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK GoogleIotCredentials (*Get JWT token for MQTT connection*) + VAR_INPUT + Execute : {REDUND_UNREPLICABLE} BOOL; + pIotMqttGoogleIotParameters : REFERENCE TO IotMqttGoogleIotParametersType; + pJWT : {REDUND_UNREPLICABLE} UDINT; (*Pointer to string. It will be filled with JWT*) + SizeOfJWT : {REDUND_UNREPLICABLE} UDINT; (*Size of destination JWT string*) + pIotMqttClientParameters : REFERENCE TO IotMqttClientParType; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + END_VAR + VAR_OUTPUT + Error : {REDUND_UNREPLICABLE} BOOL; + Done : {REDUND_UNREPLICABLE} BOOL; + Busy : {REDUND_UNREPLICABLE} BOOL; + END_VAR + VAR + _Execute : {REDUND_UNREPLICABLE} BOOL; + _hTask : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/Arm/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/Arm/IotMqtt.br new file mode 100644 index 0000000..e5ac37c Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/Arm/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/Arm/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/Arm/libIotMqtt.a new file mode 100644 index 0000000..4425429 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/Arm/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/IotMqtt.br new file mode 100644 index 0000000..d2000ec Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/IotMqtt.h b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/IotMqtt.h new file mode 100644 index 0000000..a3fc84d --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/IotMqtt.h @@ -0,0 +1,474 @@ +/* Automation Studio generated header file */ +/* Do not edit ! */ +/* IotMqtt 4.72.0 */ + +#ifndef _IOTMQTT_ +#define _IOTMQTT_ +#ifdef __cplusplus +extern "C" +{ +#endif +#ifndef _IotMqtt_VERSION +#define _IotMqtt_VERSION 4.72.0 +#endif + +#include + +#ifndef _BUR_PUBLIC +#define _BUR_PUBLIC +#endif +#ifdef _SG3 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif +#ifdef _SG4 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif +#ifdef _SGC + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif + + +/* Constants */ +#ifdef _REPLACE_CONST + #define IOTMQTT_ERR_NOT_FREE_HEAP (-10000) + #define IOTMQTT_ERR_NULL_HANDLE (-10001) + #define IOTMQTT_ERR_INVALID_HANDLE (-10002) + #define IOTMQTT_ERR_CA_CERTIFICATE (-10003) + #define IOTMQTT_ERR_CONNECTION_LOST (-10004) + #define IOTMQTT_ERR_CONNECTION_FAILED (-10005) + #define IOTMQTT_ERR_SUBSCRIBE (-10006) + #define IOTMQTT_ERR_FIFO_PUBLISH (-10007) + #define IOTMQTT_ERR_FIFO_SUBSCRIBE (-10008) + #define IOTMQTT_ERR_WRONG_PUBLISH_PAR (-10009) + #define IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR (-10010) + #define IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS (-10011) + #define IOTMQTT_ERR_WRONG_QUEUE_SIZE (-10012) + #define IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE (-10013) + #define IOTMQTT_ERR_CONN_REFUSED (-10014) + #define IOTMQTT_ERR_SENDING_TIMEDOUT (-10015) + #define IOTMQTT_WRN_ALREADY_ALLOCATED (-20001) + #define IOTMQTT_WRN_ALREADY_FREED (-20002) + #define IOTMQTT_WRN_NO_MORE_MESSAGES (-20003) + #define IOTMQTT_WRN_FAILURE_SENDING (-20004) + #define IOTMQTT_WRN_FIFO_EMPTY (-20005) + #define IOTMQTT_WRN_CLIENT_DISABLED (-20006) + #define IOTMQTT_WRN_INVALID_DATA_RCVD (-20007) + #define IOTMQTT_NO_ERR 0 + #define MAX_SUBSCRIPTION_TOPICS 50U + #define MAX_ENTRIES_RECEIVED_MESSAGES 10U + #define MAX_ENTRIES_PUBLISH_MESSAGES 500U + #define MAX_ENTRIES_SUBSCRIBE_OBJECTS 50U + #define MAX_MESSAGE_TOKEN_TABLE 1000U + #define MAX_PUBLISH_FUBS 50U + #define MAX_SUBSCRIBE_FUBS 50U +#else + _GLOBAL_CONST signed long IOTMQTT_ERR_NOT_FREE_HEAP; + _GLOBAL_CONST signed long IOTMQTT_ERR_NULL_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_INVALID_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CA_CERTIFICATE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_LOST; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_FAILED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_PUBLISH; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_PUBLISH_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_QUEUE_SIZE; + _GLOBAL_CONST signed long IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONN_REFUSED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SENDING_TIMEDOUT; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_ALLOCATED; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_FREED; + _GLOBAL_CONST signed long IOTMQTT_WRN_NO_MORE_MESSAGES; + _GLOBAL_CONST signed long IOTMQTT_WRN_FAILURE_SENDING; + _GLOBAL_CONST signed long IOTMQTT_WRN_FIFO_EMPTY; + _GLOBAL_CONST signed long IOTMQTT_WRN_CLIENT_DISABLED; + _GLOBAL_CONST signed long IOTMQTT_WRN_INVALID_DATA_RCVD; + _GLOBAL_CONST signed long IOTMQTT_NO_ERR; + _GLOBAL_CONST unsigned short MAX_SUBSCRIPTION_TOPICS; + _GLOBAL_CONST unsigned short MAX_ENTRIES_RECEIVED_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_PUBLISH_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_SUBSCRIBE_OBJECTS; + _GLOBAL_CONST unsigned short MAX_MESSAGE_TOKEN_TABLE; + _GLOBAL_CONST unsigned short MAX_PUBLISH_FUBS; + _GLOBAL_CONST unsigned short MAX_SUBSCRIBE_FUBS; +#endif + + + + +/* Datatypes and datatypes of function blocks */ +typedef enum IotMqttConnTypeEnum +{ IotMqtt_TCP, + IotMqtt_WS +} IotMqttConnTypeEnum; + +typedef enum IotMqttQosEnum +{ IotMqtt_QoS0 = 0, + IotMqtt_QoS1 = 1, + IotMqtt_QoS2 = 2 +} IotMqttQosEnum; + +typedef enum IotMqttPublishModeEnum +{ IOTMQTT_PUB_MODE_TIME, + IOTMQTT_PUB_MODE_TRIGGER, + IOTMQTT_PUB_MODE_VALUE, + IOTMQTT_PUB_MODE_TIME_TRIGGER, + IOTMQTT_PUB_MODE_TIME_VALUE, + IOTMQTT_PUB_MODE_TRIGGER_VALUE, + IOTMQTT_PUB_MODE_TIME_TRG_VALUE +} IotMqttPublishModeEnum; + +typedef enum IotMqttLogLevelEnum +{ IOTMQTT_LOG_LEVEL_ERROR, + IOTMQTT_LOG_LEVEL_PROTOCOL, + IOTMQTT_LOG_LEVEL_MAXIMUM +} IotMqttLogLevelEnum; + +typedef enum IotMqttDataFormatEnum +{ IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON +} IotMqttDataFormatEnum; + +typedef enum IotMqttConnectionStateEnum +{ IOTMQTT_DISABLED, + IOTMQTT_DISCONNECTED, + IOTMQTT_DISCONNECTING, + IOTMQTT_CONNECTED, + IOTMQTT_CONNECTING, + IOTMQTT_CONNECTION_LOST, + IOTMQTT_CONNECTION_ERROR +} IotMqttConnectionStateEnum; + +typedef enum IotMqttGoogleIotJwtAlgorithmEnum +{ IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 +} IotMqttGoogleIotJwtAlgorithmEnum; + +typedef struct IotMqttPayloadType +{ unsigned long pData; + unsigned long Len; +} IotMqttPayloadType; + +typedef struct IotMqttSubscribeInfoType +{ unsigned long NumberOfLostMessages; + unsigned long MessagesInQueue; + unsigned long AvailableMessageSlots; + unsigned long TotalReceivedMessages; +} IotMqttSubscribeInfoType; + +typedef struct IotMqttPublishInfoType +{ unsigned long MessagesPublished; + unsigned long DeliveriesCompleted; + unsigned long PublishErrorCounter; +} IotMqttPublishInfoType; + +typedef struct IotMqttClientParLastWillType +{ plcbit UseLastWill; + unsigned long Topic; + unsigned long Buffer; + unsigned long BufferLength; + enum IotMqttQosEnum QoS; + plcbit Retain; + struct IotMqttPayloadType Payload; +} IotMqttClientParLastWillType; + +typedef struct IotMqttClientParTLSType +{ plcbit UseTLS; + unsigned long CA; + unsigned long Cert; + unsigned long PrivateKey; + unsigned long PrivateKeyPassword; + unsigned long EnabledCipherSuites; + plcbit EnableServerCertAuth; +} IotMqttClientParTLSType; + +typedef struct IotMqttClientParType +{ plcstring ServerUri[256]; + unsigned short Port; + plcstring ClientID[256]; + plcstring UserName[256]; + plcstring Password[256]; + plctime KeepAliveInterval; + struct IotMqttClientParLastWillType LastWill; + plctime ConnectTimeout; + unsigned short MaxInFlight; + plctime MinRetryInterval; + plctime MaxRetryInterval; + struct IotMqttClientParTLSType TLS; + plcbit PersistentData; + plcbit AutomaticReconnect; + enum IotMqttConnTypeEnum ConnectionType; + plcbit CleanSession; + plcbit OfflinePublish; + unsigned short OfflinePublishBuffer; +} IotMqttClientParType; + +typedef struct IotMqttClientInfoType +{ enum IotMqttConnectionStateEnum ConnectionState; + unsigned long NumberActivePublishersFubs; + unsigned long NumberActiveSubscribersFubs; + unsigned long PublishMessageCount; + unsigned long SubscribeMessageCount; + unsigned long PendingMessagesCount; +} IotMqttClientInfoType; + +typedef struct IotMqttReceivedMessageType +{ unsigned long Topic; + unsigned short TopicLen; + unsigned long Buffer; + unsigned long BufferLen; + unsigned char QoS; + plcbit Retained; +} IotMqttReceivedMessageType; + +typedef struct IoTMqttComIdentType +{ unsigned long Internal; + unsigned long pThreadHandle; + unsigned long pThreadAttr; + unsigned long inst; +} IoTMqttComIdentType; + +typedef struct IotMqttConfigParametersType +{ enum IotMqttLogLevelEnum LogLevel; + plcbit UseLogger; + plcstring LoggerName[9]; + unsigned long LoggerSize; + plcbit UseFile; + plcstring LogFileName[81]; + plcstring LogFileDevice[81]; + plcbit AppendTimestamp; + plcbit OverwritteLogs; + plcstring PersistenceFileDevice[81]; +} IotMqttConfigParametersType; + +typedef struct IotMqttGoogleIotParametersType +{ plcstring ProjectID[81]; + plcstring Region[81]; + plcstring RegistryID[81]; + plcstring DeviceID[81]; + plctime ExpirationPeriod; + enum IotMqttGoogleIotJwtAlgorithmEnum Algorithm; +} IotMqttGoogleIotParametersType; + +typedef struct IotMqttClient +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + struct IotMqttClientParType Parameters; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttClientInfoType Info; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Connect; + plcbit ErrorReset; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Error; + plcbit Connected; +} IotMqttClient_typ; + +typedef struct IotMqttPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + plctime SendTimeout; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long Buffer; + unsigned long BufferLength; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + unsigned long _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Send; + plcbit Retained; + /* VAR_OUTPUT (digital) */ + plcbit Busy; + plcbit Active; + plcbit Done; + plcbit Error; + /* VAR (digital) */ + plcbit _Send; + plcbit _Active; + plcbit _ErrorReset; +} IotMqttPublish_typ; + +typedef struct IotMqttRegParPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum QoS; + plctime SendTimeout; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + enum IotMqttPublishModeEnum PublishMode; + plctime SamplingTime; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + struct IotMqttPublish _Publish; + unsigned long _Serializer; + unsigned long _prevPV; + unsigned long _addr; + unsigned long _datalen; + unsigned long _pvname; + enum IotMqttPublishModeEnum _publishmode; + enum IotMqttDataFormatEnum _mode; + plctime _samplingtime; + plctime _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Update; + plcbit Retained; + plcbit Trigger; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Busy; + plcbit Error; + /* VAR (digital) */ + plcbit _Processing; + plcbit _trig; + plcbit _enable; + plcbit _update; + plcbit _pubCmd; +} IotMqttRegParPublish_typ; + +typedef struct IotMqttSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum SubscriptionQoS; + unsigned long RecievedTopic; + unsigned long RecievedTopicSize; + unsigned char QueueSize; + unsigned long Buffer; + unsigned long BufferSize; + /* VAR_OUTPUT (analog) */ + enum IotMqttQosEnum ReceivedQoS; + signed long StatusID; + unsigned long DataSize; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + unsigned long _Internal; + unsigned long _FifoHandle; + unsigned long _FifoLock; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Read; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Subscribed; + plcbit MessageRetrieved; + plcbit Error; + plcbit Busy; + plcbit NewDataValid; + /* VAR (digital) */ + plcbit _Enable; + plcbit _Active; + plcbit _Read; + plcbit _Subscribing; +} IotMqttSubscribe_typ; + +typedef struct IotMqttRegParSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long RecievedTopic; + unsigned long QueueSize; + unsigned long ReceiveBufferSize; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + struct IotMqttSubscribe _Receive; + unsigned long _Parser; + unsigned long _RecvBuffer; + unsigned long _ReceiveBufferSize; + unsigned char _Step; + /* VAR_INPUT (digital) */ + plcbit Enable; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Busy; + plcbit Error; + plcbit UpdateNotification; +} IotMqttRegParSubscribe_typ; + +typedef struct GoogleIotCredentials +{ + /* VAR_INPUT (analog) */ + struct IotMqttGoogleIotParametersType* pIotMqttGoogleIotParameters; + unsigned long pJWT; + unsigned long SizeOfJWT; + struct IotMqttClientParType* pIotMqttClientParameters; + /* VAR (analog) */ + unsigned long _hTask; + /* VAR_INPUT (digital) */ + plcbit Execute; + /* VAR_OUTPUT (digital) */ + plcbit Error; + plcbit Done; + plcbit Busy; + /* VAR (digital) */ + plcbit _Execute; +} GoogleIotCredentials_typ; + + + +/* Prototyping of functions and function blocks */ +_BUR_PUBLIC void IotMqttClient(struct IotMqttClient* inst); +_BUR_PUBLIC void IotMqttPublish(struct IotMqttPublish* inst); +_BUR_PUBLIC void IotMqttRegParPublish(struct IotMqttRegParPublish* inst); +_BUR_PUBLIC void IotMqttSubscribe(struct IotMqttSubscribe* inst); +_BUR_PUBLIC void IotMqttRegParSubscribe(struct IotMqttRegParSubscribe* inst); +_BUR_PUBLIC void GoogleIotCredentials(struct GoogleIotCredentials* inst); +_BUR_PUBLIC signed short IotMqttConfig(struct IotMqttConfigParametersType** ConfigParameters); +_BUR_PUBLIC signed short AzureGenerateDeviceCredentials(unsigned long pConnectionString, unsigned char TimeToLive, unsigned long pParameters, unsigned long PublishTelemetryTopic, unsigned long SizeofPublishTelemetryTopic, unsigned long SubscribeTelemetryTopic, unsigned long SizeofSubscribeTelemetryTopic); + + +#ifdef __cplusplus +}; +#endif +#endif /* _IOTMQTT_ */ + diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/libIotMqtt.a new file mode 100644 index 0000000..2217229 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/SG4/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/Types.typ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/Types.typ new file mode 100644 index 0000000..42ac63c --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.72.0/Types.typ @@ -0,0 +1,159 @@ + +TYPE + IotMqttConnTypeEnum : + ( + IotMqtt_TCP, (*Use standard TCP connection*) + IotMqtt_WS (*Use connection over websockets*) + ); + IotMqttQosEnum : + ( (*The quality of service (QoS) assigned to the message. +*) + IotMqtt_QoS0 := 0, (*Fire and forget - the message may not be delivered*) + IotMqtt_QoS1 := 1, (*At least once - the message will be delivered, but may be delivered more than once in some circumstances*) + IotMqtt_QoS2 := 2 (*Once and one only - the message will be delivered exactly once.*) + ); + IotMqttPublishModeEnum : + ( + IOTMQTT_PUB_MODE_TIME, (*New data is published on a time basis. *) + IOTMQTT_PUB_MODE_TRIGGER, (*New data is published after a trigger. *) + IOTMQTT_PUB_MODE_VALUE, (*New data from the PVs is published after the value of the PV is changed. *) + IOTMQTT_PUB_MODE_TIME_TRIGGER, (*New data is published at a certain time or after a trigger. *) + IOTMQTT_PUB_MODE_TIME_VALUE, (*New data is published at a certain time or after the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TRIGGER_VALUE, (*New data is published after a trigger or the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TIME_TRG_VALUE (*New data is published at a certain time, after the value of the registered PV changes or after a trigger. *) + ); + IotMqttLogLevelEnum : + ( + IOTMQTT_LOG_LEVEL_ERROR, (*Just errors are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_PROTOCOL, (*MQTT protocol operations are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_MAXIMUM (*Diagnosis messages are written to the log file or logger*) + ); + IotMqttDataFormatEnum : + ( + IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON + ); + IotMqttConnectionStateEnum : + ( + IOTMQTT_DISABLED, (*Client FUB is disabled*) + IOTMQTT_DISCONNECTED, (*Client FUB is enabled and disconnected*) + IOTMQTT_DISCONNECTING, (*Client FUB is enabled and disconnecting*) + IOTMQTT_CONNECTED, (*Client FUB is enabled and connected*) + IOTMQTT_CONNECTING, (*Client FUB is enabled and connecting*) + IOTMQTT_CONNECTION_LOST, (*Client FUB is enabled and lost the connection*) + IOTMQTT_CONNECTION_ERROR (*Client FUB is enabled and can't connect*) + ); + IotMqttPayloadType : STRUCT + pData : UDINT; (*Pointer to data buffer*) + Len : UDINT; (*Length of data buffer*) + END_STRUCT; + IotMqttSubscribeInfoType : STRUCT + NumberOfLostMessages : UDINT; (*Number of discarded messages because fifo was full*) + MessagesInQueue : UDINT; (*Number of waiting messages in the fifo*) + AvailableMessageSlots : UDINT; (*Number of available message slots in the fifo*) + TotalReceivedMessages : UDINT; (*Total number of received messages (including discarded messages)*) + END_STRUCT; + IotMqttPublishInfoType : STRUCT + MessagesPublished : UDINT; (*Number of sent messages*) + DeliveriesCompleted : UDINT; (*Number of acknowledged messages (delivery confirmed). Only used when QoS > 0*) + PublishErrorCounter : UDINT; (*Number of errors publishing*) + END_STRUCT; + IotMqttClientParType : STRUCT + ServerUri : STRING[255]; (*String containing broker's URI*) + Port : UINT := 1883; (*TCP port number used to connect to MQTT broker*) + ClientID : STRING[255]; (*String containing ClientID. Must be unique inside the broker*) + UserName : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the user name parameter*) + Password : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the password parameter*) + KeepAliveInterval : TIME := T#30s; (*The "keep alive" interval, defines the maximum time +that should pass without communication between the client and the server +The client will ensure that at least one message travels across the +network within each keep alive period. In the absence of a data-related +message during the time period, the client sends a very small MQTT +"ping" message, which the server will acknowledge. The keep alive +interval enables the client to detect when the server is no longer +available without having to wait for the long TCP/IP timeout. +Set to 0 if you do not want any keep alive processing.*) + LastWill : IotMqttClientParLastWillType; (*LastWill is enabled when the Topic Pointer is set*) + ConnectTimeout : TIME; (*The time interval to allow a connect to complete*) + MaxInFlight : UINT; (*This controls how many messages can be in-flight simultaneously.*) + MinRetryInterval : TIME; (*Minimum retry interval . Doubled on each failed retry*) + MaxRetryInterval : TIME; (*Maximum retry interval . The doubling stops here on failed retries.*) + TLS : IotMqttClientParTLSType; (*TLS parameters*) + PersistentData : BOOL; (*Enables persistentData on QOS > 0 items*) + AutomaticReconnect : BOOL := TRUE; (*Reconnect automatically in the case of a connection being lost*) + ConnectionType : IotMqttConnTypeEnum := IotMqtt_TCP; (*Determines if the connection will use standard TCP or WebSockets*) + CleanSession : BOOL; (*When cleansession is true, the state information is discarded at connect and disconnect. Setting cleansession to false keeps the state information*) + OfflinePublish : {REDUND_UNREPLICABLE} BOOL := FALSE; (*Whether to allow messages to be sent when the client is not connected.*) + OfflinePublishBuffer : UINT := 100; (*The maximum number of messages allowed to be buffered while not connected.*) + END_STRUCT; + IotMqttClientParTLSType : STRUCT + UseTLS : BOOL; (*Set to TRUE if TLS encryption is needed*) + CA : UDINT; (*Pointer to string. Name of the ca certificate stored in the CertificateStore*) + Cert : UDINT; (*Pointer to string. Name of the client certificate file stored in the CertificateStore*) + PrivateKey : UDINT; (*Pointer to string. Name of the private key file stored in the CertificateStore*) + PrivateKeyPassword : UDINT; (*Pointer to string. The password to load the client's privateKey if encrypted*) + EnabledCipherSuites : UDINT; (*Pointer to String.The list of cipher suites that the client will present to the server during the SSL handshake. For a +full explanation of the cipher list format, please see the OpenSSL on-line documentation: +http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT +If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding +those offering no encryption- will be considered. +This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).*) + EnableServerCertAuth : BOOL; (*True/False option to enable verification of the server certificate*) + END_STRUCT; + IotMqttClientParLastWillType : STRUCT + UseLastWill : BOOL; (*Makes use of last will and testament feature*) + Topic : UDINT; (*Pointer to NULL terminated string containing topic of the message*) + Buffer : UDINT; (*Pointer to NULL terminated string with the content of the message*) + BufferLength : UDINT; (*Bufferlenght to send*) + QoS : IotMqttQosEnum; (*QoS parameter (0 - 2)*) + Retain : BOOL; (*Is the message of type retain?*) + Payload : IotMqttPayloadType; (*Content payload, to be used (instead of Buffer) when sending binary data*) + END_STRUCT; + IotMqttClientInfoType : STRUCT + ConnectionState : IotMqttConnectionStateEnum; (*Unable to find host , Connecting , Connected , Connection Lost , Retrying *) + NumberActivePublishersFubs : UDINT; (*Number of active Publishers FUBs attached to this client*) + NumberActiveSubscribersFubs : UDINT; (*Number of active Subscribers FUBs attached to this client*) + PublishMessageCount : UDINT; (*Total number of messages published by this client since enabled*) + SubscribeMessageCount : UDINT; (*Total number of messages received by this client since enabled*) + PendingMessagesCount : UDINT; (*Total number of messages pendinf of delivery*) + END_STRUCT; + IotMqttReceivedMessageType : STRUCT + Topic : UDINT; (*Pointer to the topic of the message*) + TopicLen : UINT; (*Length of the topic*) + Buffer : UDINT; (*Pointer to the buffer with the content of the message*) + BufferLen : UDINT; (*Length of the message buffer*) + QoS : USINT; (*QoS parameter (0 - 2)*) + Retained : BOOL; (*Is the message of type retain?*) + END_STRUCT; + IoTMqttComIdentType : STRUCT + Internal : UDINT; + pThreadHandle : UDINT; + pThreadAttr : UDINT; + inst : UDINT; + END_STRUCT; + IotMqttConfigParametersType : STRUCT + LogLevel : IotMqttLogLevelEnum := IOTMQTT_LOG_LEVEL_ERROR; (*Log level*) + UseLogger : BOOL := 0; (*Use logger*) + LoggerName : STRING[8] := 'IotMqtt'; (*String containing the logger name. Only used if UseLogger is set*) + LoggerSize : UDINT := 2000000; (*Size of the logger in bytes*) + UseFile : BOOL := 1; (*Use file to output the log results*) + LogFileName : STRING[80] := 'IotMqttLog.txt'; (*String containing the file name. Only used if UseFile is set*) + LogFileDevice : STRING[80] := ''; (*String containing the filedevice name. Only used if UseFile is set*) + AppendTimestamp : BOOL := FALSE; (*A timestamp will be added to the filename so that it generates unique filenames. If disabled and the file already exists, it will be overwritten*) + OverwritteLogs : BOOL := TRUE; (*If set, it will delete previous logs if the name matches and no timestamp is added*) + PersistenceFileDevice : STRING[80] := 'IOTMQTT'; (*String containing the FileDevice for persistence files*) + END_STRUCT; + IotMqttGoogleIotJwtAlgorithmEnum : + ( + IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 + ); + IotMqttGoogleIotParametersType : STRUCT + ProjectID : STRING[80]; + Region : STRING[80]; + RegistryID : STRING[80]; + DeviceID : STRING[80]; + ExpirationPeriod : TIME; (*Token expiration period*) + Algorithm : IotMqttGoogleIotJwtAlgorithmEnum; + END_STRUCT; +END_TYPE diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/Binary.lby b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/Binary.lby new file mode 100644 index 0000000..26e4d66 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/Binary.lby @@ -0,0 +1,20 @@ + + + + + Types.typ + Constants.var + IotMqtt.fun + + + + + + + + + + + + + \ No newline at end of file diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/Constants.var b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/Constants.var new file mode 100644 index 0000000..dce1395 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/Constants.var @@ -0,0 +1,43 @@ +(*Errors*) +VAR CONSTANT + IOTMQTT_ERR_NOT_FREE_HEAP : DINT := -10000; + IOTMQTT_ERR_NULL_HANDLE : DINT := -10001; + IOTMQTT_ERR_INVALID_HANDLE : DINT := -10002; + IOTMQTT_ERR_CA_CERTIFICATE : DINT := -10003; + IOTMQTT_ERR_CONNECTION_LOST : DINT := -10004; + IOTMQTT_ERR_CONNECTION_FAILED : DINT := -10005; + IOTMQTT_ERR_SUBSCRIBE : DINT := -10006; + IOTMQTT_ERR_FIFO_PUBLISH : DINT := -10007; + IOTMQTT_ERR_FIFO_SUBSCRIBE : DINT := -10008; + IOTMQTT_ERR_WRONG_PUBLISH_PAR : DINT := -10009; + IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR : DINT := -10010; + IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS : DINT := -10011; + IOTMQTT_ERR_WRONG_QUEUE_SIZE : DINT := -10012; + IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE : DINT := -10013; + IOTMQTT_ERR_CONN_REFUSED : DINT := -10014; + IOTMQTT_ERR_SENDING_TIMEDOUT : DINT := -10015; +END_VAR +(*Warnings*) +VAR CONSTANT + IOTMQTT_WRN_ALREADY_ALLOCATED : DINT := -20001; + IOTMQTT_WRN_ALREADY_FREED : DINT := -20002; + IOTMQTT_WRN_NO_MORE_MESSAGES : DINT := -20003; + IOTMQTT_WRN_FAILURE_SENDING : DINT := -20004; + IOTMQTT_WRN_FIFO_EMPTY : DINT := -20005; + IOTMQTT_WRN_CLIENT_DISABLED : DINT := -20006; + IOTMQTT_WRN_INVALID_DATA_RCVD : DINT := -20007; +END_VAR +(*OK*) +VAR CONSTANT + IOTMQTT_NO_ERR : DINT := 0; +END_VAR +(*Constants*) +VAR CONSTANT + MAX_SUBSCRIPTION_TOPICS : UINT := 50; + MAX_ENTRIES_RECEIVED_MESSAGES : UINT := 10; + MAX_ENTRIES_PUBLISH_MESSAGES : UINT := 500; + MAX_ENTRIES_SUBSCRIBE_OBJECTS : UINT := 50; + MAX_MESSAGE_TOKEN_TABLE : UINT := 1000; + MAX_PUBLISH_FUBS : UINT := 50; + MAX_SUBSCRIBE_FUBS : UINT := 50; +END_VAR diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/IotMqtt.fun b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/IotMqtt.fun new file mode 100644 index 0000000..dea6966 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/IotMqtt.fun @@ -0,0 +1,192 @@ + +{REDUND_ERROR} FUNCTION IotMqttConfig : INT (*Allows to configure library parameters. It only takes effect the first time it's called*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + ConfigParameters : REFERENCE TO IotMqttConfigParametersType; + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttClient + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + Connect : {REDUND_UNREPLICABLE} BOOL; (*If the FUB is enabled, attemps to connect with the remote MQTT broker*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Clears the current error*) + Parameters : {REDUND_UNREPLICABLE} IotMqttClientParType; (*Contains the client parameters*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and running*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttClientInfoType; (*Contains client information regarding the actual session*) + Connected : {REDUND_UNREPLICABLE} BOOL; (*TRUE if MQTT client is connected with the remote broker*) + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Send : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. Will send a new message each time is set high*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to data buffer*) + BufferLength : {REDUND_UNREPLICABLE} UDINT; (*Buffer length*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + END_VAR + VAR_OUTPUT + Busy : {REDUND_UNREPLICABLE} BOOL; (*Publishing*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Done : {REDUND_UNREPLICABLE} BOOL; (*Publish done*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Send : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _ErrorReset : {REDUND_UNREPLICABLE} BOOL; + _t0 : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParPublish + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) + Update : {REDUND_UNREPLICABLE} BOOL; (*Edfe sensitive. Will update the internal values for PvName, Mode, PublishMode and SamplingTime*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) + Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + PublishMode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; (*Which event or events will send the PV data?*) + SamplingTime : {REDUND_UNREPLICABLE} TIME; (*Sampling rate used for saving new values (used for time-based send mode). On a change, the new value is only applied on a rising edge of Update*) + Trigger : {REDUND_UNREPLICABLE} BOOL; (*Trigger (used for the recording mode that works with a trigger).*) + END_VAR + VAR_OUTPUT + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*Working in serialization + sending*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttPublishInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Publish : {REDUND_UNREPLICABLE} IotMqttPublish; + _Serializer : {REDUND_UNREPLICABLE} UDINT; + _Processing : {REDUND_UNREPLICABLE} BOOL; + _prevPV : {REDUND_UNREPLICABLE} UDINT; + _trig : {REDUND_UNREPLICABLE} BOOL; + _addr : {REDUND_UNREPLICABLE} UDINT; + _datalen : {REDUND_UNREPLICABLE} UDINT; + _enable : {REDUND_UNREPLICABLE} BOOL; + _pvname : {REDUND_UNREPLICABLE} UDINT; + _publishmode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; + _mode : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; + _update : {REDUND_UNREPLICABLE} BOOL; + _samplingtime : {REDUND_UNREPLICABLE} TIME; + _t0 : {REDUND_UNREPLICABLE} TIME; + _pubCmd : {REDUND_UNREPLICABLE} BOOL; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB. Subscription will take place at enable of the FUB, if the associated IotMqttClient FUB is enabled and connected.*) + Read : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. When activaded it will deliver one message from the internal FIFO*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + SubscriptionQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + RecievedTopicSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the received topic buffer*) + QueueSize : {REDUND_UNREPLICABLE} USINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to memory area where the content of the read messages will be stored*) + BufferSize : {REDUND_UNREPLICABLE} UDINT; (*Size of the memory area where the content of the read messages will be stored*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The read message from the FIFO has the "Retain" flag*) + ReceivedQoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The read message from the FIFO has this QoS*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Subscribed : {REDUND_UNREPLICABLE} BOOL; (*Subscription completed succesfully*) + MessageRetrieved : {REDUND_UNREPLICABLE} BOOL; (*Read operation completed succesfully*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + NewDataValid : {REDUND_UNREPLICABLE} BOOL; (*Is TRUE if new data was received with the last FB call*) + DataSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the Buffer array used in bytes*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Enable : {REDUND_UNREPLICABLE} BOOL; + _Active : {REDUND_UNREPLICABLE} BOOL; + _Internal : {REDUND_UNREPLICABLE} UDINT; + _FifoHandle : {REDUND_UNREPLICABLE} UDINT; + _Read : {REDUND_UNREPLICABLE} BOOL; + _Subscribing : {REDUND_UNREPLICABLE} BOOL; + _FifoLock : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK IotMqttRegParSubscribe + VAR_INPUT + IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) + Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) + DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) + Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) + QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*QoS that will be used when subscribing*) + RecievedTopic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name that triggered the subscribtion. This is usefull when using Wildcards*) + QueueSize : {REDUND_UNREPLICABLE} UDINT; (*Length of the receive queue. When the FIFO queue is full, old frames are overwritten and output parameter NumberOfLostFrames starts counting.*) + ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + END_VAR + VAR_OUTPUT + Retained : {REDUND_UNREPLICABLE} BOOL; (*The received message has the "Retain" flag*) + Active : {REDUND_UNREPLICABLE} BOOL; (*FUB is enabled and client running*) + Busy : {REDUND_UNREPLICABLE} BOOL; (*FUB is working*) + Error : {REDUND_UNREPLICABLE} BOOL; (*There is an error, Check StatusID for more information*) + UpdateNotification : {REDUND_UNREPLICABLE} BOOL; (*registered PV contains new values. This is automatically reset after one cycle.*) + StatusID : {REDUND_UNREPLICABLE} DINT; (*Gives information about the error*) + Info : {REDUND_UNREPLICABLE} IotMqttSubscribeInfoType; (*Contains information about the FUB instance*) + END_VAR + VAR + _Receive : {REDUND_UNREPLICABLE} IotMqttSubscribe; + _Parser : {REDUND_UNREPLICABLE} UDINT; + _RecvBuffer : {REDUND_UNREPLICABLE} UDINT; + _ReceiveBufferSize : {REDUND_UNREPLICABLE} UDINT; (*This is the maximum size of the buffer used to store each received message. It must be large enough to contain the largest message what the FUB will receive.*) + _Step : {REDUND_UNREPLICABLE} USINT; + END_VAR +END_FUNCTION_BLOCK + +{REDUND_ERROR} FUNCTION AzureGenerateDeviceCredentials : INT (*Given an AzureIoT Hub device connection string, and the "TimeToLive" parameter, will populate the needed parameters for connecting it*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*) + VAR_INPUT + pConnectionString : UDINT; (*Pointer to string with the connection string*) + TimeToLive : USINT; (*Time in hours that the password will be valid*) + pParameters : UDINT; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + PublishTelemetryTopic : UDINT; (*Pointer to string to store the publish topic*) + SizeofPublishTelemetryTopic : UDINT; (*Size of PublishTelemetryTopic variable*) + SubscribeTelemetryTopic : UDINT; (*Pointer to string to store the subscribe topic*) + SizeofSubscribeTelemetryTopic : UDINT; (*Size of SubscribeTelemetryTopic variable*) + END_VAR +END_FUNCTION + +{REDUND_UNREPLICABLE} FUNCTION_BLOCK GoogleIotCredentials (*Get JWT token for MQTT connection*) + VAR_INPUT + Execute : {REDUND_UNREPLICABLE} BOOL; + pIotMqttGoogleIotParameters : REFERENCE TO IotMqttGoogleIotParametersType; + pJWT : {REDUND_UNREPLICABLE} UDINT; (*Pointer to string. It will be filled with JWT*) + SizeOfJWT : {REDUND_UNREPLICABLE} UDINT; (*Size of destination JWT string*) + pIotMqttClientParameters : REFERENCE TO IotMqttClientParType; (*Pointer to the client parameters structure. Some of them will be automatically filled by the function*) + END_VAR + VAR_OUTPUT + Error : {REDUND_UNREPLICABLE} BOOL; + Done : {REDUND_UNREPLICABLE} BOOL; + Busy : {REDUND_UNREPLICABLE} BOOL; + END_VAR + VAR + _Execute : {REDUND_UNREPLICABLE} BOOL; + _hTask : {REDUND_UNREPLICABLE} UDINT; + END_VAR +END_FUNCTION_BLOCK diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/Arm/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/Arm/IotMqtt.br new file mode 100644 index 0000000..4591253 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/Arm/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/Arm/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/Arm/libIotMqtt.a new file mode 100644 index 0000000..4425429 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/Arm/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/IotMqtt.br b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/IotMqtt.br new file mode 100644 index 0000000..3b07ab0 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/IotMqtt.br differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/IotMqtt.h b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/IotMqtt.h new file mode 100644 index 0000000..cf8def6 --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/IotMqtt.h @@ -0,0 +1,474 @@ +/* Automation Studio generated header file */ +/* Do not edit ! */ +/* IotMqtt 4.73.0 */ + +#ifndef _IOTMQTT_ +#define _IOTMQTT_ +#ifdef __cplusplus +extern "C" +{ +#endif +#ifndef _IotMqtt_VERSION +#define _IotMqtt_VERSION 4.73.0 +#endif + +#include + +#ifndef _BUR_PUBLIC +#define _BUR_PUBLIC +#endif +#ifdef _SG3 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif +#ifdef _SG4 + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif +#ifdef _SGC + #include "astime.h" + #include "AsIecCon.h" + #include "AsHW.h" + #include "ArEventLog.h" + #include "sys_lib.h" + #include "FileIO.h" + #include "ArCert.h" + #include "AsETH.h" + #include "AsIODiag.h" +#endif + + +/* Constants */ +#ifdef _REPLACE_CONST + #define IOTMQTT_ERR_NOT_FREE_HEAP (-10000) + #define IOTMQTT_ERR_NULL_HANDLE (-10001) + #define IOTMQTT_ERR_INVALID_HANDLE (-10002) + #define IOTMQTT_ERR_CA_CERTIFICATE (-10003) + #define IOTMQTT_ERR_CONNECTION_LOST (-10004) + #define IOTMQTT_ERR_CONNECTION_FAILED (-10005) + #define IOTMQTT_ERR_SUBSCRIBE (-10006) + #define IOTMQTT_ERR_FIFO_PUBLISH (-10007) + #define IOTMQTT_ERR_FIFO_SUBSCRIBE (-10008) + #define IOTMQTT_ERR_WRONG_PUBLISH_PAR (-10009) + #define IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR (-10010) + #define IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS (-10011) + #define IOTMQTT_ERR_WRONG_QUEUE_SIZE (-10012) + #define IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE (-10013) + #define IOTMQTT_ERR_CONN_REFUSED (-10014) + #define IOTMQTT_ERR_SENDING_TIMEDOUT (-10015) + #define IOTMQTT_WRN_ALREADY_ALLOCATED (-20001) + #define IOTMQTT_WRN_ALREADY_FREED (-20002) + #define IOTMQTT_WRN_NO_MORE_MESSAGES (-20003) + #define IOTMQTT_WRN_FAILURE_SENDING (-20004) + #define IOTMQTT_WRN_FIFO_EMPTY (-20005) + #define IOTMQTT_WRN_CLIENT_DISABLED (-20006) + #define IOTMQTT_WRN_INVALID_DATA_RCVD (-20007) + #define IOTMQTT_NO_ERR 0 + #define MAX_SUBSCRIPTION_TOPICS 50U + #define MAX_ENTRIES_RECEIVED_MESSAGES 10U + #define MAX_ENTRIES_PUBLISH_MESSAGES 500U + #define MAX_ENTRIES_SUBSCRIBE_OBJECTS 50U + #define MAX_MESSAGE_TOKEN_TABLE 1000U + #define MAX_PUBLISH_FUBS 50U + #define MAX_SUBSCRIBE_FUBS 50U +#else + _GLOBAL_CONST signed long IOTMQTT_ERR_NOT_FREE_HEAP; + _GLOBAL_CONST signed long IOTMQTT_ERR_NULL_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_INVALID_HANDLE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CA_CERTIFICATE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_LOST; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONNECTION_FAILED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_PUBLISH; + _GLOBAL_CONST signed long IOTMQTT_ERR_FIFO_SUBSCRIBE; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_PUBLISH_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_SUBSCRIBE_PAR; + _GLOBAL_CONST signed long IOTMQTT_ERR_SUBSCRIBE_MAX_TOPICS; + _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_QUEUE_SIZE; + _GLOBAL_CONST signed long IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE; + _GLOBAL_CONST signed long IOTMQTT_ERR_CONN_REFUSED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SENDING_TIMEDOUT; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_ALLOCATED; + _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_FREED; + _GLOBAL_CONST signed long IOTMQTT_WRN_NO_MORE_MESSAGES; + _GLOBAL_CONST signed long IOTMQTT_WRN_FAILURE_SENDING; + _GLOBAL_CONST signed long IOTMQTT_WRN_FIFO_EMPTY; + _GLOBAL_CONST signed long IOTMQTT_WRN_CLIENT_DISABLED; + _GLOBAL_CONST signed long IOTMQTT_WRN_INVALID_DATA_RCVD; + _GLOBAL_CONST signed long IOTMQTT_NO_ERR; + _GLOBAL_CONST unsigned short MAX_SUBSCRIPTION_TOPICS; + _GLOBAL_CONST unsigned short MAX_ENTRIES_RECEIVED_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_PUBLISH_MESSAGES; + _GLOBAL_CONST unsigned short MAX_ENTRIES_SUBSCRIBE_OBJECTS; + _GLOBAL_CONST unsigned short MAX_MESSAGE_TOKEN_TABLE; + _GLOBAL_CONST unsigned short MAX_PUBLISH_FUBS; + _GLOBAL_CONST unsigned short MAX_SUBSCRIBE_FUBS; +#endif + + + + +/* Datatypes and datatypes of function blocks */ +typedef enum IotMqttConnTypeEnum +{ IotMqtt_TCP, + IotMqtt_WS +} IotMqttConnTypeEnum; + +typedef enum IotMqttQosEnum +{ IotMqtt_QoS0 = 0, + IotMqtt_QoS1 = 1, + IotMqtt_QoS2 = 2 +} IotMqttQosEnum; + +typedef enum IotMqttPublishModeEnum +{ IOTMQTT_PUB_MODE_TIME, + IOTMQTT_PUB_MODE_TRIGGER, + IOTMQTT_PUB_MODE_VALUE, + IOTMQTT_PUB_MODE_TIME_TRIGGER, + IOTMQTT_PUB_MODE_TIME_VALUE, + IOTMQTT_PUB_MODE_TRIGGER_VALUE, + IOTMQTT_PUB_MODE_TIME_TRG_VALUE +} IotMqttPublishModeEnum; + +typedef enum IotMqttLogLevelEnum +{ IOTMQTT_LOG_LEVEL_ERROR, + IOTMQTT_LOG_LEVEL_PROTOCOL, + IOTMQTT_LOG_LEVEL_MAXIMUM +} IotMqttLogLevelEnum; + +typedef enum IotMqttDataFormatEnum +{ IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON +} IotMqttDataFormatEnum; + +typedef enum IotMqttConnectionStateEnum +{ IOTMQTT_DISABLED, + IOTMQTT_DISCONNECTED, + IOTMQTT_DISCONNECTING, + IOTMQTT_CONNECTED, + IOTMQTT_CONNECTING, + IOTMQTT_CONNECTION_LOST, + IOTMQTT_CONNECTION_ERROR +} IotMqttConnectionStateEnum; + +typedef enum IotMqttGoogleIotJwtAlgorithmEnum +{ IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 +} IotMqttGoogleIotJwtAlgorithmEnum; + +typedef struct IotMqttPayloadType +{ unsigned long pData; + unsigned long Len; +} IotMqttPayloadType; + +typedef struct IotMqttSubscribeInfoType +{ unsigned long NumberOfLostMessages; + unsigned long MessagesInQueue; + unsigned long AvailableMessageSlots; + unsigned long TotalReceivedMessages; +} IotMqttSubscribeInfoType; + +typedef struct IotMqttPublishInfoType +{ unsigned long MessagesPublished; + unsigned long DeliveriesCompleted; + unsigned long PublishErrorCounter; +} IotMqttPublishInfoType; + +typedef struct IotMqttClientParLastWillType +{ plcbit UseLastWill; + unsigned long Topic; + unsigned long Buffer; + unsigned long BufferLength; + enum IotMqttQosEnum QoS; + plcbit Retain; + struct IotMqttPayloadType Payload; +} IotMqttClientParLastWillType; + +typedef struct IotMqttClientParTLSType +{ plcbit UseTLS; + unsigned long CA; + unsigned long Cert; + unsigned long PrivateKey; + unsigned long PrivateKeyPassword; + unsigned long EnabledCipherSuites; + plcbit EnableServerCertAuth; +} IotMqttClientParTLSType; + +typedef struct IotMqttClientParType +{ plcstring ServerUri[256]; + unsigned short Port; + plcstring ClientID[256]; + plcstring UserName[256]; + plcstring Password[256]; + plctime KeepAliveInterval; + struct IotMqttClientParLastWillType LastWill; + plctime ConnectTimeout; + unsigned short MaxInFlight; + plctime MinRetryInterval; + plctime MaxRetryInterval; + struct IotMqttClientParTLSType TLS; + plcbit PersistentData; + plcbit AutomaticReconnect; + enum IotMqttConnTypeEnum ConnectionType; + plcbit CleanSession; + plcbit OfflinePublish; + unsigned short OfflinePublishBuffer; +} IotMqttClientParType; + +typedef struct IotMqttClientInfoType +{ enum IotMqttConnectionStateEnum ConnectionState; + unsigned long NumberActivePublishersFubs; + unsigned long NumberActiveSubscribersFubs; + unsigned long PublishMessageCount; + unsigned long SubscribeMessageCount; + unsigned long PendingMessagesCount; +} IotMqttClientInfoType; + +typedef struct IotMqttReceivedMessageType +{ unsigned long Topic; + unsigned short TopicLen; + unsigned long Buffer; + unsigned long BufferLen; + unsigned char QoS; + plcbit Retained; +} IotMqttReceivedMessageType; + +typedef struct IoTMqttComIdentType +{ unsigned long Internal; + unsigned long pThreadHandle; + unsigned long pThreadAttr; + unsigned long inst; +} IoTMqttComIdentType; + +typedef struct IotMqttConfigParametersType +{ enum IotMqttLogLevelEnum LogLevel; + plcbit UseLogger; + plcstring LoggerName[9]; + unsigned long LoggerSize; + plcbit UseFile; + plcstring LogFileName[81]; + plcstring LogFileDevice[81]; + plcbit AppendTimestamp; + plcbit OverwritteLogs; + plcstring PersistenceFileDevice[81]; +} IotMqttConfigParametersType; + +typedef struct IotMqttGoogleIotParametersType +{ plcstring ProjectID[81]; + plcstring Region[81]; + plcstring RegistryID[81]; + plcstring DeviceID[81]; + plctime ExpirationPeriod; + enum IotMqttGoogleIotJwtAlgorithmEnum Algorithm; +} IotMqttGoogleIotParametersType; + +typedef struct IotMqttClient +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + struct IotMqttClientParType Parameters; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttClientInfoType Info; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Connect; + plcbit ErrorReset; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Error; + plcbit Connected; +} IotMqttClient_typ; + +typedef struct IotMqttPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + plctime SendTimeout; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long Buffer; + unsigned long BufferLength; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + unsigned long _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Send; + plcbit Retained; + /* VAR_OUTPUT (digital) */ + plcbit Busy; + plcbit Active; + plcbit Done; + plcbit Error; + /* VAR (digital) */ + plcbit _Send; + plcbit _Active; + plcbit _ErrorReset; +} IotMqttPublish_typ; + +typedef struct IotMqttRegParPublish +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum QoS; + plctime SendTimeout; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + enum IotMqttPublishModeEnum PublishMode; + plctime SamplingTime; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + struct IotMqttPublish _Publish; + unsigned long _Serializer; + unsigned long _prevPV; + unsigned long _addr; + unsigned long _datalen; + unsigned long _pvname; + enum IotMqttPublishModeEnum _publishmode; + enum IotMqttDataFormatEnum _mode; + plctime _samplingtime; + plctime _t0; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit ErrorReset; + plcbit Update; + plcbit Retained; + plcbit Trigger; + /* VAR_OUTPUT (digital) */ + plcbit Active; + plcbit Busy; + plcbit Error; + /* VAR (digital) */ + plcbit _Processing; + plcbit _trig; + plcbit _enable; + plcbit _update; + plcbit _pubCmd; +} IotMqttRegParPublish_typ; + +typedef struct IotMqttSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long Topic; + enum IotMqttQosEnum SubscriptionQoS; + unsigned long RecievedTopic; + unsigned long RecievedTopicSize; + unsigned char QueueSize; + unsigned long Buffer; + unsigned long BufferSize; + /* VAR_OUTPUT (analog) */ + enum IotMqttQosEnum ReceivedQoS; + signed long StatusID; + unsigned long DataSize; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + unsigned long _Internal; + unsigned long _FifoHandle; + unsigned long _FifoLock; + /* VAR_INPUT (digital) */ + plcbit Enable; + plcbit Read; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Subscribed; + plcbit MessageRetrieved; + plcbit Error; + plcbit Busy; + plcbit NewDataValid; + /* VAR (digital) */ + plcbit _Enable; + plcbit _Active; + plcbit _Read; + plcbit _Subscribing; +} IotMqttSubscribe_typ; + +typedef struct IotMqttRegParSubscribe +{ + /* VAR_INPUT (analog) */ + struct IoTMqttComIdentType* IotMqttLink; + unsigned long PvName; + enum IotMqttDataFormatEnum DataFormat; + unsigned long Topic; + enum IotMqttQosEnum QoS; + unsigned long RecievedTopic; + unsigned long QueueSize; + unsigned long ReceiveBufferSize; + /* VAR_OUTPUT (analog) */ + signed long StatusID; + struct IotMqttSubscribeInfoType Info; + /* VAR (analog) */ + struct IotMqttSubscribe _Receive; + unsigned long _Parser; + unsigned long _RecvBuffer; + unsigned long _ReceiveBufferSize; + unsigned char _Step; + /* VAR_INPUT (digital) */ + plcbit Enable; + /* VAR_OUTPUT (digital) */ + plcbit Retained; + plcbit Active; + plcbit Busy; + plcbit Error; + plcbit UpdateNotification; +} IotMqttRegParSubscribe_typ; + +typedef struct GoogleIotCredentials +{ + /* VAR_INPUT (analog) */ + struct IotMqttGoogleIotParametersType* pIotMqttGoogleIotParameters; + unsigned long pJWT; + unsigned long SizeOfJWT; + struct IotMqttClientParType* pIotMqttClientParameters; + /* VAR (analog) */ + unsigned long _hTask; + /* VAR_INPUT (digital) */ + plcbit Execute; + /* VAR_OUTPUT (digital) */ + plcbit Error; + plcbit Done; + plcbit Busy; + /* VAR (digital) */ + plcbit _Execute; +} GoogleIotCredentials_typ; + + + +/* Prototyping of functions and function blocks */ +_BUR_PUBLIC void IotMqttClient(struct IotMqttClient* inst); +_BUR_PUBLIC void IotMqttPublish(struct IotMqttPublish* inst); +_BUR_PUBLIC void IotMqttRegParPublish(struct IotMqttRegParPublish* inst); +_BUR_PUBLIC void IotMqttSubscribe(struct IotMqttSubscribe* inst); +_BUR_PUBLIC void IotMqttRegParSubscribe(struct IotMqttRegParSubscribe* inst); +_BUR_PUBLIC void GoogleIotCredentials(struct GoogleIotCredentials* inst); +_BUR_PUBLIC signed short IotMqttConfig(struct IotMqttConfigParametersType** ConfigParameters); +_BUR_PUBLIC signed short AzureGenerateDeviceCredentials(unsigned long pConnectionString, unsigned char TimeToLive, unsigned long pParameters, unsigned long PublishTelemetryTopic, unsigned long SizeofPublishTelemetryTopic, unsigned long SubscribeTelemetryTopic, unsigned long SizeofSubscribeTelemetryTopic); + + +#ifdef __cplusplus +}; +#endif +#endif /* _IOTMQTT_ */ + diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/libIotMqtt.a b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/libIotMqtt.a new file mode 100644 index 0000000..2217229 Binary files /dev/null and b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/SG4/libIotMqtt.a differ diff --git a/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/Types.typ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/Types.typ new file mode 100644 index 0000000..42ac63c --- /dev/null +++ b/IotMqtt/1.3.8-rev03/IotMqtt/V4.73.0/Types.typ @@ -0,0 +1,159 @@ + +TYPE + IotMqttConnTypeEnum : + ( + IotMqtt_TCP, (*Use standard TCP connection*) + IotMqtt_WS (*Use connection over websockets*) + ); + IotMqttQosEnum : + ( (*The quality of service (QoS) assigned to the message. +*) + IotMqtt_QoS0 := 0, (*Fire and forget - the message may not be delivered*) + IotMqtt_QoS1 := 1, (*At least once - the message will be delivered, but may be delivered more than once in some circumstances*) + IotMqtt_QoS2 := 2 (*Once and one only - the message will be delivered exactly once.*) + ); + IotMqttPublishModeEnum : + ( + IOTMQTT_PUB_MODE_TIME, (*New data is published on a time basis. *) + IOTMQTT_PUB_MODE_TRIGGER, (*New data is published after a trigger. *) + IOTMQTT_PUB_MODE_VALUE, (*New data from the PVs is published after the value of the PV is changed. *) + IOTMQTT_PUB_MODE_TIME_TRIGGER, (*New data is published at a certain time or after a trigger. *) + IOTMQTT_PUB_MODE_TIME_VALUE, (*New data is published at a certain time or after the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TRIGGER_VALUE, (*New data is published after a trigger or the value of the registered PV changes. *) + IOTMQTT_PUB_MODE_TIME_TRG_VALUE (*New data is published at a certain time, after the value of the registered PV changes or after a trigger. *) + ); + IotMqttLogLevelEnum : + ( + IOTMQTT_LOG_LEVEL_ERROR, (*Just errors are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_PROTOCOL, (*MQTT protocol operations are written to the log file or logger*) + IOTMQTT_LOG_LEVEL_MAXIMUM (*Diagnosis messages are written to the log file or logger*) + ); + IotMqttDataFormatEnum : + ( + IOTMQTT_VAR_BINARY, + IOTMQTT_VAR_JSON + ); + IotMqttConnectionStateEnum : + ( + IOTMQTT_DISABLED, (*Client FUB is disabled*) + IOTMQTT_DISCONNECTED, (*Client FUB is enabled and disconnected*) + IOTMQTT_DISCONNECTING, (*Client FUB is enabled and disconnecting*) + IOTMQTT_CONNECTED, (*Client FUB is enabled and connected*) + IOTMQTT_CONNECTING, (*Client FUB is enabled and connecting*) + IOTMQTT_CONNECTION_LOST, (*Client FUB is enabled and lost the connection*) + IOTMQTT_CONNECTION_ERROR (*Client FUB is enabled and can't connect*) + ); + IotMqttPayloadType : STRUCT + pData : UDINT; (*Pointer to data buffer*) + Len : UDINT; (*Length of data buffer*) + END_STRUCT; + IotMqttSubscribeInfoType : STRUCT + NumberOfLostMessages : UDINT; (*Number of discarded messages because fifo was full*) + MessagesInQueue : UDINT; (*Number of waiting messages in the fifo*) + AvailableMessageSlots : UDINT; (*Number of available message slots in the fifo*) + TotalReceivedMessages : UDINT; (*Total number of received messages (including discarded messages)*) + END_STRUCT; + IotMqttPublishInfoType : STRUCT + MessagesPublished : UDINT; (*Number of sent messages*) + DeliveriesCompleted : UDINT; (*Number of acknowledged messages (delivery confirmed). Only used when QoS > 0*) + PublishErrorCounter : UDINT; (*Number of errors publishing*) + END_STRUCT; + IotMqttClientParType : STRUCT + ServerUri : STRING[255]; (*String containing broker's URI*) + Port : UINT := 1883; (*TCP port number used to connect to MQTT broker*) + ClientID : STRING[255]; (*String containing ClientID. Must be unique inside the broker*) + UserName : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the user name parameter*) + Password : STRING[255]; (*String. MQTT servers that support the MQTT v3.1 protocol provide authentication and authorisation by user name and password. This is the password parameter*) + KeepAliveInterval : TIME := T#30s; (*The "keep alive" interval, defines the maximum time +that should pass without communication between the client and the server +The client will ensure that at least one message travels across the +network within each keep alive period. In the absence of a data-related +message during the time period, the client sends a very small MQTT +"ping" message, which the server will acknowledge. The keep alive +interval enables the client to detect when the server is no longer +available without having to wait for the long TCP/IP timeout. +Set to 0 if you do not want any keep alive processing.*) + LastWill : IotMqttClientParLastWillType; (*LastWill is enabled when the Topic Pointer is set*) + ConnectTimeout : TIME; (*The time interval to allow a connect to complete*) + MaxInFlight : UINT; (*This controls how many messages can be in-flight simultaneously.*) + MinRetryInterval : TIME; (*Minimum retry interval . Doubled on each failed retry*) + MaxRetryInterval : TIME; (*Maximum retry interval . The doubling stops here on failed retries.*) + TLS : IotMqttClientParTLSType; (*TLS parameters*) + PersistentData : BOOL; (*Enables persistentData on QOS > 0 items*) + AutomaticReconnect : BOOL := TRUE; (*Reconnect automatically in the case of a connection being lost*) + ConnectionType : IotMqttConnTypeEnum := IotMqtt_TCP; (*Determines if the connection will use standard TCP or WebSockets*) + CleanSession : BOOL; (*When cleansession is true, the state information is discarded at connect and disconnect. Setting cleansession to false keeps the state information*) + OfflinePublish : {REDUND_UNREPLICABLE} BOOL := FALSE; (*Whether to allow messages to be sent when the client is not connected.*) + OfflinePublishBuffer : UINT := 100; (*The maximum number of messages allowed to be buffered while not connected.*) + END_STRUCT; + IotMqttClientParTLSType : STRUCT + UseTLS : BOOL; (*Set to TRUE if TLS encryption is needed*) + CA : UDINT; (*Pointer to string. Name of the ca certificate stored in the CertificateStore*) + Cert : UDINT; (*Pointer to string. Name of the client certificate file stored in the CertificateStore*) + PrivateKey : UDINT; (*Pointer to string. Name of the private key file stored in the CertificateStore*) + PrivateKeyPassword : UDINT; (*Pointer to string. The password to load the client's privateKey if encrypted*) + EnabledCipherSuites : UDINT; (*Pointer to String.The list of cipher suites that the client will present to the server during the SSL handshake. For a +full explanation of the cipher list format, please see the OpenSSL on-line documentation: +http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT +If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding +those offering no encryption- will be considered. +This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).*) + EnableServerCertAuth : BOOL; (*True/False option to enable verification of the server certificate*) + END_STRUCT; + IotMqttClientParLastWillType : STRUCT + UseLastWill : BOOL; (*Makes use of last will and testament feature*) + Topic : UDINT; (*Pointer to NULL terminated string containing topic of the message*) + Buffer : UDINT; (*Pointer to NULL terminated string with the content of the message*) + BufferLength : UDINT; (*Bufferlenght to send*) + QoS : IotMqttQosEnum; (*QoS parameter (0 - 2)*) + Retain : BOOL; (*Is the message of type retain?*) + Payload : IotMqttPayloadType; (*Content payload, to be used (instead of Buffer) when sending binary data*) + END_STRUCT; + IotMqttClientInfoType : STRUCT + ConnectionState : IotMqttConnectionStateEnum; (*Unable to find host , Connecting , Connected , Connection Lost , Retrying *) + NumberActivePublishersFubs : UDINT; (*Number of active Publishers FUBs attached to this client*) + NumberActiveSubscribersFubs : UDINT; (*Number of active Subscribers FUBs attached to this client*) + PublishMessageCount : UDINT; (*Total number of messages published by this client since enabled*) + SubscribeMessageCount : UDINT; (*Total number of messages received by this client since enabled*) + PendingMessagesCount : UDINT; (*Total number of messages pendinf of delivery*) + END_STRUCT; + IotMqttReceivedMessageType : STRUCT + Topic : UDINT; (*Pointer to the topic of the message*) + TopicLen : UINT; (*Length of the topic*) + Buffer : UDINT; (*Pointer to the buffer with the content of the message*) + BufferLen : UDINT; (*Length of the message buffer*) + QoS : USINT; (*QoS parameter (0 - 2)*) + Retained : BOOL; (*Is the message of type retain?*) + END_STRUCT; + IoTMqttComIdentType : STRUCT + Internal : UDINT; + pThreadHandle : UDINT; + pThreadAttr : UDINT; + inst : UDINT; + END_STRUCT; + IotMqttConfigParametersType : STRUCT + LogLevel : IotMqttLogLevelEnum := IOTMQTT_LOG_LEVEL_ERROR; (*Log level*) + UseLogger : BOOL := 0; (*Use logger*) + LoggerName : STRING[8] := 'IotMqtt'; (*String containing the logger name. Only used if UseLogger is set*) + LoggerSize : UDINT := 2000000; (*Size of the logger in bytes*) + UseFile : BOOL := 1; (*Use file to output the log results*) + LogFileName : STRING[80] := 'IotMqttLog.txt'; (*String containing the file name. Only used if UseFile is set*) + LogFileDevice : STRING[80] := ''; (*String containing the filedevice name. Only used if UseFile is set*) + AppendTimestamp : BOOL := FALSE; (*A timestamp will be added to the filename so that it generates unique filenames. If disabled and the file already exists, it will be overwritten*) + OverwritteLogs : BOOL := TRUE; (*If set, it will delete previous logs if the name matches and no timestamp is added*) + PersistenceFileDevice : STRING[80] := 'IOTMQTT'; (*String containing the FileDevice for persistence files*) + END_STRUCT; + IotMqttGoogleIotJwtAlgorithmEnum : + ( + IotMqttGoogleIotAlgorithm_RS256, + IotMqttGoogleIotAlgorithm_ES256 + ); + IotMqttGoogleIotParametersType : STRUCT + ProjectID : STRING[80]; + Region : STRING[80]; + RegistryID : STRING[80]; + DeviceID : STRING[80]; + ExpirationPeriod : TIME; (*Token expiration period*) + Algorithm : IotMqttGoogleIotJwtAlgorithmEnum; + END_STRUCT; +END_TYPE diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/Binary.lby b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/Binary.lby new file mode 100644 index 0000000..c9b6f57 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/Binary.lby @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Base64.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Base64.h new file mode 100644 index 0000000..7022ce8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Base64.h @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2018 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(BASE64_H) +#define BASE64_H + +/** type for size of a buffer, it saves passing around @p size_t (unsigned long long or unsigned long int) */ +typedef unsigned int b64_size_t; +/** type for raw base64 data */ +typedef unsigned char b64_data_t; + +/** + * Decodes base64 data + * + * @param[out] out decoded data + * @param[in] out_len length of output buffer + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the amount of data decoded + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_decode( b64_data_t *out, b64_size_t out_len, + const char *in, b64_size_t in_len ); + +/** + * Size of buffer required to decode base64 data + * + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the decoded string would require + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_decodeLength( const char *in, b64_size_t in_len ); + +/** + * Encodes base64 data + * + * @param[out] out encode base64 string + * @param[in] out_len length of output buffer + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the amount of data encoded + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_encode( char *out, b64_size_t out_len, + const b64_data_t *in, b64_size_t in_len ); + +/** + * Size of buffer required to encode base64 data + * + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the encoded string would require + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_encodeLength( const b64_data_t *in, b64_size_t in_len ); + +#endif /* BASE64_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Clients.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Clients.h new file mode 100644 index 0000000..a3ddb1f --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Clients.h @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - add SSL support + * Ian Craggs - fix for bug 413429 - connectionLost not called + * Ian Craggs - change will payload to binary + * Ian Craggs - password to binary + * Ian Craggs - MQTT 5 support + *******************************************************************************/ + +#if !defined(CLIENTS_H) +#define CLIENTS_H + +#include +#include "MQTTTime.h" +#if defined(OPENSSL) +#if defined(_WIN32) || defined(_WIN64) +#include +#endif +#include +#endif +#include "MQTTClient.h" +#include "LinkedList.h" +#include "MQTTClientPersistence.h" + +/** + * Stored publication data to minimize copying + */ +typedef struct +{ + char *topic; + int topiclen; + char* payload; + int payloadlen; + int refcount; + uint8_t mask[4]; +} Publications; + +/** + * Client publication message data + */ +typedef struct +{ + int qos; + int retain; + int msgid; + int MQTTVersion; + MQTTProperties properties; + Publications *publish; + START_TIME_TYPE lastTouch; /**> used for retry and expiry */ + char nextMessageType; /**> PUBREC, PUBREL, PUBCOMP */ + int len; /**> length of the whole structure+data */ +} Messages; + +/** + * Client will message data + */ +typedef struct +{ + char *topic; + int payloadlen; + void *payload; + int retained; + int qos; +} willMessages; + +typedef struct +{ + int socket; + START_TIME_TYPE lastSent; + START_TIME_TYPE lastReceived; + START_TIME_TYPE lastPing; +#if defined(OPENSSL) + SSL* ssl; + SSL_CTX* ctx; + char *https_proxy; + char *https_proxy_auth; +#endif + char *http_proxy; + char *http_proxy_auth; + int websocket; /**< socket has been upgraded to use web sockets */ + char *websocket_key; + const MQTTClient_nameValue* httpHeaders; +} networkHandles; + + +/* connection states */ +/** no connection in progress, see connected value */ +#define NOT_IN_PROGRESS 0x0 +/** TCP connection in progress */ +#define TCP_IN_PROGRESS 0x1 +/** SSL connection in progress */ +#define SSL_IN_PROGRESS 0x2 +/** Websocket connection in progress */ +#define WEBSOCKET_IN_PROGRESS 0x3 +/** TCP completed, waiting for MQTT ACK */ +#define WAIT_FOR_CONNACK 0x4 +/** Proxy connection in progress */ +#define PROXY_CONNECT_IN_PROGRESS 0x5 +/** Disconnecting */ +#define DISCONNECTING -2 + +/** + * Data related to one client + */ +typedef struct +{ + char* clientID; /**< the string id of the client */ + const char* username; /**< MQTT v3.1 user name */ + int passwordlen; /**< MQTT password length */ + const void* password; /**< MQTT v3.1 binary password */ + unsigned int cleansession : 1; /**< MQTT V3 clean session flag */ + unsigned int cleanstart : 1; /**< MQTT V5 clean start flag */ + unsigned int connected : 1; /**< whether it is currently connected */ + unsigned int good : 1; /**< if we have an error on the socket we turn this off */ + unsigned int ping_outstanding : 1; + signed int connect_state : 4; + networkHandles net; /**< network info for this client */ + int msgID; /**< the MQTT message id */ + int keepAliveInterval; /**< the MQTT keep alive interval */ + int retryInterval; + int maxInflightMessages; /**< the max number of inflight outbound messages we allow */ + willMessages* will; /**< the MQTT will message, if any */ + List* inboundMsgs; /**< inbound in flight messages */ + List* outboundMsgs; /**< outbound in flight messages */ + List* messageQueue; /**< inbound complete but undelivered messages */ + unsigned int qentry_seqno; + void* phandle; /**< the persistence handle */ + MQTTClient_persistence* persistence; /**< a persistence implementation */ + MQTTPersistence_beforeWrite* beforeWrite; /**< persistence write callback */ + MQTTPersistence_afterRead* afterRead; /**< persistence read callback */ + void* beforeWrite_context; /**< context to be used with the persistence beforeWrite callbacks */ + void* afterRead_context; /**< context to be used with the persistence afterRead callback */ + void* context; /**< calling context - used when calling disconnect_internal */ + int MQTTVersion; /**< the version of MQTT being used, 3, 4 or 5 */ + int sessionExpiry; /**< MQTT 5 session expiry */ + char* httpProxy; /**< HTTP proxy for websockets */ + char* httpsProxy; /**< HTTPS proxy for websockets */ +#if defined(OPENSSL) + MQTTClient_SSLOptions *sslopts; /**< the SSL/TLS connect options */ + SSL_SESSION* session; /**< SSL session pointer for fast handhake */ +#endif +} Clients; + +int clientIDCompare(void* a, void* b); +int clientSocketCompare(void* a, void* b); + +/** + * Configuration data related to all clients + */ +typedef struct +{ + const char* version; + List* clients; +} ClientStates; + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Heap.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Heap.h new file mode 100644 index 0000000..f89a760 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Heap.h @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - use tree data structure instead of list + *******************************************************************************/ + + +#if !defined(HEAP_H) +#define HEAP_H + +#if defined(HIGH_PERFORMANCE) +#define NO_HEAP_TRACKING 1 +#endif + +#define PAHO_MEMORY_ERROR -99 + +#include "MQTTExportDeclarations.h" + +#include +#include + +#if !defined(NO_HEAP_TRACKING) + +#if !defined(TREE_C) +/** + * redefines malloc to use "mymalloc" so that heap allocation can be tracked + * @param x the size of the item to be allocated + * @return the pointer to the item allocated, or NULL + */ +#define malloc(x) mymalloc(__FILE__, __LINE__, x) + +/** + * redefines realloc to use "myrealloc" so that heap allocation can be tracked + * @param a the heap item to be reallocated + * @param b the new size of the item + * @return the new pointer to the heap item + */ +#define realloc(a, b) myrealloc(__FILE__, __LINE__, a, b) + +/** + * redefines free to use "myfree" so that heap allocation can be tracked + * @param x the size of the item to be freed + */ +#define free(x) myfree(__FILE__, __LINE__, x) + +#endif + +/** + * Information about the state of the heap. + */ +typedef struct +{ + size_t current_size; /**< current size of the heap in bytes */ + size_t max_size; /**< max size the heap has reached in bytes */ +} heap_info; + +#if defined(__cplusplus) + extern "C" { +#endif + +void* mymalloc(char*, int, size_t size); +void* myrealloc(char*, int, void* p, size_t size); +void myfree(char*, int, void* p); + +void Heap_scan(FILE* file); +int Heap_initialize(void); +void Heap_terminate(void); +LIBMQTT_API heap_info* Heap_get_info(void); +int HeapDump(FILE* file); +int HeapDumpString(FILE* file, char* str); +void* Heap_findItem(void* p); +void Heap_unlink(char* file, int line, void* p); +#ifdef __cplusplus + } +#endif + +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/LinkedList.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/LinkedList.h new file mode 100644 index 0000000..e390012 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/LinkedList.h @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + * Ian Craggs - change size types from int to size_t + *******************************************************************************/ + +#if !defined(LINKEDLIST_H) +#define LINKEDLIST_H + +#include /* for size_t definition */ + +/*BE +defm defList(T) + +def T concat Item +{ + at 4 + n32 ptr T concat Item suppress "next" + at 0 + n32 ptr T concat Item suppress "prev" + at 8 + n32 ptr T id2str(T) +} + +def T concat List +{ + n32 ptr T concat Item suppress "first" + n32 ptr T concat Item suppress "last" + n32 ptr T concat Item suppress "current" + n32 dec "count" + n32 suppress "size" +} +endm + +defList(INT) +defList(STRING) +defList(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct ListElementStruct +{ + struct ListElementStruct *prev, /**< pointer to previous list element */ + *next; /**< pointer to next list element */ + void* content; /**< pointer to element content */ +} ListElement; + + +/** + * Structure to hold all data for one list + */ +typedef struct +{ + ListElement *first, /**< first element in the list */ + *last, /**< last element in the list */ + *current; /**< current element in the list, for iteration */ + int count; /**< no of items */ + size_t size; /**< heap storage used */ +} List; + +void ListZero(List*); +List* ListInitialize(void); + +ListElement* ListAppend(List* aList, void* content, size_t size); +void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, size_t size); +ListElement* ListInsert(List* aList, void* content, size_t size, ListElement* index); + +int ListRemove(List* aList, void* content); +int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*)); +void* ListDetachHead(List* aList); +int ListRemoveHead(List* aList); +void* ListPopTail(List* aList); + +int ListDetach(List* aList, void* content); +int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*)); + +void ListFree(List* aList); +void ListEmpty(List* aList); +void ListFreeNoContent(List* aList); + +ListElement* ListNextElement(List* aList, ListElement** pos); +ListElement* ListPrevElement(List* aList, ListElement** pos); + +ListElement* ListFind(List* aList, void* content); +ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*)); + +int intcompare(void* a, void* b); +int stringcompare(void* a, void* b); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Log.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Log.h new file mode 100644 index 0000000..102e31d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Log.h @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + *******************************************************************************/ + +#if !defined(LOG_H) +#define LOG_H + +/*BE +map LOG_LEVELS +{ + "TRACE_MAXIMUM" 1 + "TRACE_MEDIUM" 2 + "TRACE_MINIMUM" 3 + "TRACE_PROTOCOL" 4 + + "ERROR" 5 + "SEVERE" 6 + "FATAL" 7 +} +BE*/ + +enum LOG_LEVELS { + INVALID_LEVEL = -1, + TRACE_MAXIMUM = 1, + TRACE_MEDIUM, + TRACE_MINIMUM, + TRACE_PROTOCOL, + LOG_ERROR, + LOG_SEVERE, + LOG_FATAL, +}; + + +/*BE +def trace_settings_type +{ + n32 map LOG_LEVELS "trace_level" + n32 dec "max_trace_entries" + n32 dec "trace_output_level" +} +BE*/ +typedef struct +{ + enum LOG_LEVELS trace_level; /**< trace level */ + int max_trace_entries; /**< max no of entries in the trace buffer */ + enum LOG_LEVELS trace_output_level; /**< trace level to output to destination */ +} trace_settings_type; + +extern trace_settings_type trace_settings; + +#define LOG_PROTOCOL TRACE_PROTOCOL +#define TRACE_MAX TRACE_MAXIMUM +#define TRACE_MIN TRACE_MINIMUM +#define TRACE_MED TRACE_MEDIUM + +typedef struct +{ + const char* name; + const char* value; +} Log_nameValue; + +int Log_initialize(Log_nameValue*); +void Log_terminate(void); + +void Log(enum LOG_LEVELS, int, const char *, ...); +void Log_stackTrace(enum LOG_LEVELS, int, int, int, const char*, int, int*); + +typedef void Log_traceCallback(enum LOG_LEVELS level, const char *message); +void Log_setTraceCallback(Log_traceCallback* callback); +void Log_setTraceLevel(enum LOG_LEVELS level); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTAsync.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTAsync.h new file mode 100644 index 0000000..f728ba5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTAsync.h @@ -0,0 +1,2345 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation + * Ian Craggs, Allan Stockdill-Mander - SSL connections + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - fix for bug 444103 - success/failure callbacks not invoked + * Ian Craggs - automatic reconnect and offline buffering (send while disconnected) + * Ian Craggs - binary will message + * Ian Craggs - binary password + * Ian Craggs - remove const on eyecatchers #168 + * Ian Craggs - MQTT 5.0 + *******************************************************************************/ + +/********************************************************************/ + +/** + * @cond MQTTAsync_main + * @mainpage Asynchronous MQTT client library for C + * + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An Asynchronous MQTT client library for C. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the Asynchronous MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions
  • + *
  • Connect the client to an MQTT server
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref publish
  • + *
  • @ref subscribe
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
  • @ref auto_reconnect
  • + *
  • @ref offline_publish
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTASYNC_H) +#define MQTTASYNC_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTASYNC_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTASYNC_FAILURE -1 + +/* error code -2 is MQTTAsync_PERSISTENCE_ERROR */ + +#define MQTTASYNC_PERSISTENCE_ERROR -2 + +/** + * Return code: The client is disconnected. + */ +#define MQTTASYNC_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTASYNC_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTASYNC_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTASYNC_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTASYNC_BAD_STRUCTURE -8 +/** + * Return code: A qos parameter is not 0, 1 or 2 + */ +#define MQTTASYNC_BAD_QOS -9 +/** + * Return code: All 65535 MQTT msgids are being used + */ +#define MQTTASYNC_NO_MORE_MSGIDS -10 +/** + * Return code: the request is being discarded when not complete + */ +#define MQTTASYNC_OPERATION_INCOMPLETE -11 +/** + * Return code: no more messages can be buffered + */ +#define MQTTASYNC_MAX_BUFFERED_MESSAGES -12 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTASYNC_SSL_NOT_SUPPORTED -13 + /** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if the TLS version of the library + * is linked with. + */ +#define MQTTASYNC_BAD_PROTOCOL -14 + /** + * Return code: don't use options for another version of MQTT + */ + #define MQTTASYNC_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the client's version of MQTT + */ + #define MQTTASYNC_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic + */ + #define MQTTASYNC_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 +/** + * MQTT version to connect with: 5 + */ +#define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTAsync_init_options; + +#define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt (0) + */ +LIBMQTT_API void MQTTAsync_global_init(MQTTAsync_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTAsync_create(). + */ +typedef void* MQTTAsync; +/** + * A value representing an MQTT message. A token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTAsync_publish(), + * MQTTAsync_publishMessage(), + * MQTTAsync_deliveryComplete(), and + * MQTTAsync_getPendingTokens()). + */ +typedef int MQTTAsync_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTAsync_publishMessage(), + * MQTTAsync_publish(), MQTTAsync_receive(), MQTTAsync_freeMessage() + * and MQTTAsync_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. This is an output parameter only. + */ + int dup; + /** The message identifier is reserved for internal use by the + * MQTT client and server. It is an output parameter only - writing + * to it will serve no purpose. It contains the MQTT message id of + * an incoming publish message. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTAsync_message; + +#define MQTTAsync_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTAsync_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTAsync_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTAsync_freeMessage must be called. + * To free the topic name storage, ::MQTTAsync_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTAsync_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTAsync_messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages to the server. The function is + * registered with the client library by passing it as an argument to MQTTAsync_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTAsync_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param token The ::MQTTAsync_token associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the tokens returned from calls to + * MQTTAsync_send() and MQTTAsync_sendMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTAsync_deliveryComplete(void* context, MQTTAsync_token token); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTAsync_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connectionLost(void* context, char* cause); + + +/** + * This is a callback function, which will be called when the client + * library successfully connects. This is superfluous when the connection + * is made in response to a MQTTAsync_connect call, because the onSuccess + * callback can be used. It is intended for use when automatic reconnect + * is enabled, so that when a reconnection attempt succeeds in the background, + * the application is notified and can take any required actions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connected(void* context, char* cause); + +/** + * This is a callback function, which will be called when the client + * library receives a disconnect packet. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param properties the properties in the disconnect packet. + * @param properties the reason code from the disconnect packet + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTAsync_disconnected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDisconnected(MQTTAsync handle, void* context, MQTTAsync_disconnected* co); + +/** The connect options that can be updated before an automatic reconnect. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQCD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name parameter. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + const char* username; + /** + * The password parameter of the MQTT authentication. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; +} MQTTAsync_connectData; + +#define MQTTAsync_connectData_initializer {{'M', 'Q', 'C', 'D'}, 0, NULL, {0, NULL}} + +/** + * This is a callback function which will allow the client application to update the + * connection data. + * @param data The connection data which can be modified by the application. + * @return Return a non-zero value to update the connect data, zero to keep the same data. + */ +typedef int MQTTAsync_updateConnectOptions(void* context, MQTTAsync_connectData* data); + +/** + * Sets the MQTTAsync_updateConnectOptions() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_updateConnectOptions() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setUpdateConnectOptions(MQTTAsync handle, void* context, MQTTAsync_updateConnectOptions* co); + +/** + * Sets the MQTTPersistence_beforeWrite() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setBeforePersistenceWrite(MQTTAsync handle, void* context, MQTTPersistence_beforeWrite* co); + + +/** + * Sets the MQTTPersistence_afterRead() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setAfterPersistenceRead(MQTTAsync handle, void* context, MQTTPersistence_afterRead* co); + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** A numeric code identifying the error. */ + int code; + /** Optional text explaining the error. Can be NULL. */ + const char *message; +} MQTTAsync_failureData; + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQFD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** The MQTT reason code returned. */ + enum MQTTReasonCodes reasonCode; + /** The MQTT properties on the ack, if any. */ + MQTTProperties properties; + /** A numeric code identifying the MQTT client library error. */ + int code; + /** Optional further text explaining the error. Can be NULL. */ + const char *message; + /** Packet type on which the failure occurred - used for publish QoS 1/2 exchanges*/ + int packet_type; +} MQTTAsync_failureData5; + +#define MQTTAsync_failureData5_initializer {{'M', 'Q', 'F', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, 0, NULL} + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribe, the granted QoS of the subscription returned by the server. + * Also for subscribeMany, if only 1 subscription was requested. */ + int qos; + /** For subscribeMany, if more than one subscription was requested, + * the list of granted QoSs of the subscriptions returned by the server. */ + int* qosList; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + } alt; +} MQTTAsync_successData; + + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + char struct_id[4]; /**< The eyecatcher for this structure. Will be MQSD. */ + int struct_version; /**< The version number of this structure. Will be 0 */ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + enum MQTTReasonCodes reasonCode; /**< MQTT V5 reason code returned */ + MQTTProperties properties; /**< MQTT V5 properties returned, if any */ + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } sub; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + /** For unsubscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } unsub; + } alt; +} MQTTAsync_successData5; + +#define MQTTAsync_successData5_initializer {{'M', 'Q', 'S', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer} + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onSuccess. + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess5(void* context, MQTTAsync_successData5* response); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure(void* context, MQTTAsync_failureData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onFailure. + * The application must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure5(void* context, MQTTAsync_failureData5* response); + +/** Structure to define call options. For MQTT 5.0 there is input data as well as that + * describing the response method. So there is now also a synonym ::MQTTAsync_callOptions + * to better reflect the use. This responseOptions name is kept for backward + * compatibility. + */ +typedef struct MQTTAsync_responseOptions +{ + /** The eyecatcher for this structure. Must be MQTR */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * if 0, no MQTTV5 options */ + int struct_version; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the API call fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * A token is returned from the call. It can be used to track + * the state of this request, both in the callbacks and in future calls + * such as ::MQTTAsync_waitForCompletion. + */ + MQTTAsync_token token; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /* + * MQTT V5 subscribe options, when used with subscribe only. + */ + MQTTSubscribe_options subscribeOptions; + /* + * MQTT V5 subscribe option count, when used with subscribeMany only. + * The number of entries in the subscribe_options_list array. + */ + int subscribeOptionsCount; + /* + * MQTT V5 subscribe option array, when used with subscribeMany only. + */ + MQTTSubscribe_options* subscribeOptionsList; +} MQTTAsync_responseOptions; + +#define MQTTAsync_responseOptions_initializer { {'M', 'Q', 'T', 'R'}, 1, NULL, NULL, 0, 0, NULL, NULL, MQTTProperties_initializer, MQTTSubscribe_options_initializer, 0, NULL} + +/** A synonym for responseOptions to better reflect its usage since MQTT 5.0 */ +typedef struct MQTTAsync_responseOptions MQTTAsync_callOptions; +#define MQTTAsync_callOptions_initializer MQTTAsync_responseOptions_initializer + +/** + * This function sets the global callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. If this callback is not set, an error will be returned. + * You must set this callback because otherwise there would be + * no way to deliver any incoming messages. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl, + MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc); + +/** + * This function sets the callback function for a connection lost event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed the callback functions to provide + * access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ + +LIBMQTT_API int MQTTAsync_setConnectionLostCallback(MQTTAsync handle, void* context, + MQTTAsync_connectionLost* cl); + +/** + * This function sets the callback function for a message arrived event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. You can set this to NULL if your application doesn't handle + * receipt of messages. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setMessageArrivedCallback(MQTTAsync handle, void* context, + MQTTAsync_messageArrived* ma); + +/** + * This function sets the callback function for a delivery complete event + * for a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDeliveryCompleteCallback(MQTTAsync handle, void* context, + MQTTAsync_deliveryComplete* dc); + +/** + * Sets the MQTTAsync_connected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co); + + +/** + * Reconnects a client with the previously used connect options. Connect + * must have previously been called for this to work. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_reconnect(MQTTAsync handle); + + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTAsync_persistence). See also MQTTAsync_destroy(). + * @param handle A pointer to an ::MQTTAsync handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of + * the library is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTASYNC_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTAsync_create(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTAsync_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2 or 3 + * 0 means no MQTTVersion + * 1 means no allowDisconnectedSendAtAnyTime, deleteOldestMessages, restoreMessages + * 2 means no persistQoS0 + */ + int struct_version; + /** Whether to allow messages to be sent when the client library is not connected. */ + int sendWhileDisconnected; + /** The maximum number of messages allowed to be buffered while not connected. */ + int maxBufferedMessages; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; + /** + * Allow sending of messages while disconnected before a first successful connect. + */ + int allowDisconnectedSendAtAnyTime; + /* + * When the maximum number of buffered messages is reached, delete the oldest rather than the newest. + */ + int deleteOldestMessages; + /* + * Restore messages from persistence on create - or clear it. + */ + int restoreMessages; + /* + * Persist QoS0 publish commands - an option to not persist them. + */ + int persistQoS0; +} MQTTAsync_createOptions; + +#define MQTTAsync_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_DEFAULT, 0, 0, 1, 1} + +#define MQTTAsync_createOptions_initializer5 { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_5, 0, 0, 1, 1} + + +LIBMQTT_API int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTAsync_createOptions* options); + +/** + * MQTTAsync_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTAsync_willOptions + * structure is passed in the MQTTAsync_connectOptions structure used in the + * MQTTAsync_connect() call that connects the client to the server. The pointer + * to MQTTAsync_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 indicates no binary will message support + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTAsync_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTAsync_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTAsync_willOptions; + +#define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTAsync_SSLOptions; + +#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** Utility structure where name/value pairs are needed */ +typedef struct +{ + const char* name; /**< name string */ + const char* value; /**< value string */ +} MQTTAsync_nameValue; + +/** + * MQTTAsync_connectOptions defines several settings that control the way the + * client connects to an MQTT server. Default values are set in + * MQTTAsync_connectOptions_initializer. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3 4 5 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no automatic reconnect options + * 4 signifies no binary password option (just string) + * 5 signifies no MQTTV5 properties + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + * Set to 0 if you do not want any keep alive processing. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTAsync_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This controls how many messages can be in-flight simultaneously. + */ + int maxInflight; + /** + * This is a pointer to an MQTTAsync_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTAsync_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTAsync_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTAsync_SSLOptions* ssl; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * The number of entries in the serverURIs array. + */ + int serverURIcount; + /** + * An array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a domain name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + */ + int MQTTVersion; + /** + * Reconnect automatically in the case of a connection being lost? + */ + int automaticReconnect; + /** + * Minimum retry interval in seconds. Doubled on each failed retry. + */ + int minRetryInterval; + /** + * Maximum retry interval in seconds. The doubling stops here on failed retries. + */ + int maxRetryInterval; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * MQTT V5 properties for connect + */ + MQTTProperties *connectProperties; + /** + * MQTT V5 properties for the will message in the connect + */ + MQTTProperties *willProperties; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * HTTP headers for websockets + */ + const MQTTAsync_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTAsync_connectOptions; + + +#define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + + +/** + * This function attempts to connect a previously-created client (see + * MQTTAsync_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTAsync_setCallbacks() prior to MQTTAsync_connect(). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options A pointer to a valid MQTTAsync_connectOptions + * structure. + * @return ::MQTTASYNC_SUCCESS if the client connect request was accepted. + * If the client was unable to connect to the server, an error code is + * returned via the onFailure callback, if set. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options); + +/** Options for the ::MQTTAsync_disconnect call */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTD. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. 0 signifies no V5 properties */ + int struct_version; + /** + * The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + */ + int timeout; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /** + * Reason code for MQTTV5 disconnect + */ + enum MQTTReasonCodes reasonCode; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; +} MQTTAsync_disconnectOptions; + +#define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 0, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +#define MQTTAsync_disconnectOptions_initializer5 { {'M', 'Q', 'T', 'D'}, 1, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTAsync_connectOptions.cleansession and MQTTAsync_connect()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions* options); + + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTAsync_isConnected(MQTTAsync handle); + + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTAsync_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTAsync_subscribe(MQTTAsync handle, const char* topic, int qos, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTAsync_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char* const* topic, const int* qos, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTAsync_unsubscribe(MQTTAsync handle, const char* topic, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const* topic, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to publish a message to a given topic (see also + * ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * This is optional and can be set to NULL. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_send(MQTTAsync handle, const char* destinationName, int payloadlen, const void* payload, int qos, + int retained, MQTTAsync_responseOptions* response); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTAsync_publish()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param msg A pointer to a valid MQTTAsync_message structure containing + * the payload and attributes of the message to be published. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_sendMessage(MQTTAsync handle, const char* destinationName, const MQTTAsync_message* msg, MQTTAsync_responseOptions* response); + + +/** + * This function sets a pointer to an array of tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param tokens The address of a pointer to an ::MQTTAsync_token. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTASYNC_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens); + +/** + * Tests whether a request corresponding to a token is complete. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @return 1 if the request has been completed, 0 if not. + */ +#define MQTTASYNC_TRUE 1 +LIBMQTT_API int MQTTAsync_isComplete(MQTTAsync handle, MQTTAsync_token token); + + +/** + * Waits for a request corresponding to a token to complete. This only works for + * messages with QoS greater than 0. A QoS 0 message has no MQTT token. + * This function will always return ::MQTTASYNC_SUCCESS for a QoS 0 message. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @param timeout the maximum time to wait for completion, in milliseconds + * @return ::MQTTASYNC_SUCCESS if the request has been completed in the time allocated, + * ::MQTTASYNC_FAILURE or ::MQTTASYNC_DISCONNECTED if not. + */ +LIBMQTT_API int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token token, unsigned long timeout); + + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTAsync_free() library function. + * @param msg The address of a pointer to the ::MQTTAsync_message structure + * to be freed. + */ +LIBMQTT_API void MQTTAsync_freeMessage(MQTTAsync_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTAsync_free(void* ptr); + +/** + * This function is used to allocate memory to be used or freed by the MQTT C client library, + * especially the data in the ::MQTTPersistence_afterRead and ::MQTTPersistence_beforeWrite + * callbacks. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. + * @param size The size of the memory to be allocated. + */ +LIBMQTT_API void* MQTTAsync_malloc(size_t size); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTAsync_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTAsync + * structure to be freed. + */ +LIBMQTT_API void MQTTAsync_destroy(MQTTAsync* handle); + + + +enum MQTTASYNC_TRACE_LEVELS +{ + MQTTASYNC_TRACE_MAXIMUM = 1, + MQTTASYNC_TRACE_MEDIUM, + MQTTASYNC_TRACE_MINIMUM, + MQTTASYNC_TRACE_PROTOCOL, + MQTTASYNC_TRACE_ERROR, + MQTTASYNC_TRACE_SEVERE, + MQTTASYNC_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTAsync_setTraceLevel(enum MQTTASYNC_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTAsync_traceCallback(enum MQTTASYNC_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTAsync_setTraceCallback(MQTTAsync_traceCallback* callback); + +/** + * This function returns version information about the library. + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void); + +/** + * Returns a pointer to a string representation of the error code, or NULL. + * Do not free after use. Returns NULL if the error code is unknown. + * @param code the MQTTASYNC_ return code. + * @return a static string representation of the error code. + */ +LIBMQTT_API const char* MQTTAsync_strerror(int code); + + +/*! + * @cond MQTTAsync_main + * @page async Threading + * The client application runs on several threads. + * Processing of handshaking and maintaining + * the network connection is performed in the background. + * This API is thread safe: functions may be called by multiple application + * threads. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(), + * MQTTAsync_connectionLost() and MQTTAsync_deliveryComplete()). + * In addition, some functions allow success and failure callbacks to be set + * for individual requests, in the ::MQTTAsync_responseOptions structure. Applications + * can be written as a chain of callback functions. + * + * @page callbacks Callbacks + * Any function from this API may be used within a callback. It is not advisable to + * use ::MQTTAsync_waitForCompletion within a callback, however, as it is the only + * API call that may take some time to complete, which may cause unpredictable + * behaviour. All the other API calls are intended to complete quickly, starting + * a request in the background, with success or failure notified by other callbacks. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * A log message will be written to highlight the issue, but it is up + * to the application to protect against this situation. + * + * @page auto_reconnect Automatic Reconnect + * The ability for the client library to reconnect automatically in the event + * of a connection failure was added in 1.1. The connection lost callback + * allows a flexible response to the loss of a connection, so almost any + * behaviour can be implemented in that way. Automatic reconnect does have the + * advantage of being a little simpler to use. + * + * To switch on automatic reconnect, the connect options field + * automaticReconnect should be set to non-zero. The minimum and maximum times + * before the next connection attempt can also be set, the defaults being 1 and + * 60 seconds. At each failure to reconnect, the retry interval is doubled until + * the maximum value is reached, and there it stays until the connection is + * successfully re-established whereupon it is reset. + * + * When a reconnection attempt is successful, the ::MQTTAsync_connected callback + * function is invoked, if set by calling ::MQTTAsync_setConnected. This allows + * the application to take any actions needed, such as amending subscriptions. + * + * @page offline_publish Publish While Disconnected + * This feature was not originally available because with persistence enabled, + * messages could be stored locally without ever knowing if they could be sent. + * The client application could have created the client with an erroneous broker + * address or port for instance. + * + * To enable messages to be published when the application is disconnected + * ::MQTTAsync_createWithOptions must be used instead of ::MQTTAsync_create to + * create the client object. The ::MQTTAsync_createOptions field sendWhileDisconnected + * must be set to non-zero, and the maxBufferedMessages field set as required - + * the default being 100. + * + * ::MQTTAsync_getPendingTokens can be called to return the ids of the messages + * waiting to be sent, or for which the sending process has not completed. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTAsync_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page publish Publication example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed\n"); + finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + finished = 1; +} + +void onSendFailure(void* context, MQTTAsync_failureData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message send failed token %d error code %d\n", response->token, response->code); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +void onSend(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message with token value %d delivery confirmed\n", response->token); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response ? response->code : 0); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + MQTTAsync_message pubmsg = MQTTAsync_message_initializer; + int rc; + + printf("Successful connection\n"); + opts.onSuccess = onSend; + opts.onFailure = onSendFailure; + opts.context = client; + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start sendMessage, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +int messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* m) +{ + // not expecting any messages + return 1; +} + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to create client object, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + if ((rc = MQTTAsync_setCallbacks(client, NULL, connlost, messageArrived, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callback, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (!finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + MQTTAsync_destroy(&client); + return rc; +} + + * @endcode + * @page subscribe Subscription example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int disc_finished = 0; +int subscribed = 0; +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + if (cause) + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTAsync_freeMessage(&message); + MQTTAsync_free(topicName); + return 1; +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed, rc %d\n", response->code); + disc_finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + disc_finished = 1; +} + +void onSubscribe(void* context, MQTTAsync_successData* response) +{ + printf("Subscribe succeeded\n"); + subscribed = 1; +} + +void onSubscribeFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Subscribe failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + int rc; + + printf("Successful connection\n"); + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + opts.onSuccess = onSubscribe; + opts.onFailure = onSubscribeFailure; + opts.context = client; + if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start subscribe, return code %d\n", rc); + finished = 1; + } +} + + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer; + int rc; + int ch; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) + != MQTTASYNC_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTAsync_setCallbacks(client, client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + while (!subscribed && !finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + if (finished) + goto exit; + + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + disc_opts.onSuccess = onDisconnect; + disc_opts.onFailure = onDisconnectFailure; + if ((rc = MQTTAsync_disconnect(client, &disc_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + while (!disc_finished) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + +destroy_exit: + MQTTAsync_destroy(&client); +exit: + return rc; +} + + * @endcode +* @page tracing Tracing + * + * Runtime tracing can be controlled by environment variables or API calls. + * + * #### Environment variables + * + * Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable. + * A value of ON, or stdout, prints to stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * #### Trace API calls + * + * MQTTAsync_traceCallback() is used to set a callback function which is called whenever trace + * information is available. This will be the same information as that printed if the + * environment variables were used to control the trace. + * + * The MQTTAsync_setTraceLevel() calls is used to set the maximum level of trace entries that will be + * passed to the callback function. The levels are: + * 1. ::MQTTASYNC_TRACE_MAXIMUM + * 2. ::MQTTASYNC_TRACE_MEDIUM + * 3. ::MQTTASYNC_TRACE_MINIMUM + * 4. ::MQTTASYNC_TRACE_PROTOCOL + * 5. ::MQTTASYNC_TRACE_ERROR + * 6. ::MQTTASYNC_TRACE_SEVERE + * 7. ::MQTTASYNC_TRACE_FATAL + * + * Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned. + * Choosing ::MQTTASYNC_TRACE_ERROR will cause ERROR, SEVERE and FATAL trace entries to be returned + * to the callback function. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ + +#if defined(__cplusplus) + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTAsyncUtils.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTAsyncUtils.h new file mode 100644 index 0000000..42a3145 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTAsyncUtils.h @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + +#if !defined(MQTTASYNCUTILS_H_) +#define MQTTASYNCUTILS_H_ + +#include "MQTTPacket.h" +#include "Thread.h" + +#define URI_TCP "tcp://" +#define URI_WS "ws://" +#define URI_WSS "wss://" + +enum MQTTAsync_threadStates +{ + STOPPED, STARTING, RUNNING, STOPPING +}; + +typedef struct +{ + MQTTAsync_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} qEntry; + +typedef struct +{ + int type; + MQTTAsync_onSuccess* onSuccess; + MQTTAsync_onFailure* onFailure; + MQTTAsync_onSuccess5* onSuccess5; + MQTTAsync_onFailure5* onFailure5; + MQTTAsync_token token; + void* context; + START_TIME_TYPE start_time; + MQTTProperties properties; + union + { + struct + { + int count; + char** topics; + int* qoss; + MQTTSubscribe_options opts; + MQTTSubscribe_options* optlist; + } sub; + struct + { + int count; + char** topics; + } unsub; + struct + { + char* destinationName; + int payloadlen; + void* payload; + int qos; + int retained; + } pub; + struct + { + int internal; + int timeout; + enum MQTTReasonCodes reasonCode; + } dis; + struct + { + int currentURI; + int MQTTVersion; /**< current MQTT version being used to connect */ + } conn; + } details; +} MQTTAsync_command; + +typedef struct MQTTAsync_struct +{ + char* serverURI; + int ssl; + int websocket; + Clients* c; + + /* "Global", to the client, callback definitions */ + MQTTAsync_connectionLost* cl; + MQTTAsync_messageArrived* ma; + MQTTAsync_deliveryComplete* dc; + void* clContext; /* the context to be associated with the conn lost callback*/ + void* maContext; /* the context to be associated with the msg arrived callback*/ + void* dcContext; /* the context to be associated with the deliv complete callback*/ + + MQTTAsync_connected* connected; + void* connected_context; /* the context to be associated with the connected callback*/ + + MQTTAsync_disconnected* disconnected; + void* disconnected_context; /* the context to be associated with the disconnected callback*/ + + MQTTAsync_updateConnectOptions* updateConnectOptions; + void* updateConnectOptions_context; + + /* Each time connect is called, we store the options that were used. These are reused in + any call to reconnect, or an automatic reconnect attempt */ + MQTTAsync_command connect; /* Connect operation properties */ + MQTTAsync_command disconnect; /* Disconnect operation properties */ + MQTTAsync_command* pending_write; /* Is there a socket write pending? */ + + List* responses; + unsigned int command_seqno; + + MQTTPacket* pack; + + /* added for offline buffering */ + MQTTAsync_createOptions* createOptions; + int shouldBeConnected; + int noBufferedMessages; /* the current number of buffered (publish) messages for this client */ + + /* added for automatic reconnect */ + int automaticReconnect; + int minRetryInterval; + int maxRetryInterval; + int serverURIcount; + char** serverURIs; + int connectTimeout; + + int currentInterval; + int currentIntervalBase; + START_TIME_TYPE lastConnectionFailedTime; + int retrying; + int reconnectNow; + + /* MQTT V5 properties */ + MQTTProperties* connectProps; + MQTTProperties* willProps; + +} MQTTAsyncs; + +typedef struct +{ + MQTTAsync_command command; + MQTTAsyncs* client; + unsigned int seqno; /* only used on restore */ + int not_restored; + char* key; /* if not_restored, this holds the key */ +} MQTTAsync_queuedCommand; + +void MQTTAsync_lock_mutex(mutex_type amutex); +void MQTTAsync_unlock_mutex(mutex_type amutex); +void MQTTAsync_terminate(void); +#if !defined(NO_PERSISTENCE) +int MQTTAsync_restoreCommands(MQTTAsyncs* client); +#endif +int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size); +void MQTTAsync_emptyMessageQueue(Clients* client); +void MQTTAsync_freeResponses(MQTTAsyncs* m); +void MQTTAsync_freeCommands(MQTTAsyncs* m); +int MQTTAsync_unpersistCommandsAndMessages(Clients* c); +void MQTTAsync_closeSession(Clients* client, enum MQTTReasonCodes reasonCode, MQTTProperties* props); +int MQTTAsync_disconnect1(MQTTAsync handle, const MQTTAsync_disconnectOptions* options, int internal); +int MQTTAsync_assignMsgId(MQTTAsyncs* m); +int MQTTAsync_getNoBufferedMessages(MQTTAsyncs* m); +void MQTTAsync_writeComplete(int socket, int rc); +void setRetryLoopInterval(int keepalive); + +#if defined(_WIN32) || defined(_WIN64) +#else +#define WINAPI +#endif + +thread_return_type WINAPI MQTTAsync_sendThread(void* n); +thread_return_type WINAPI MQTTAsync_receiveThread(void* n); + +#endif /* MQTTASYNCUTILS_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTClient.h new file mode 100644 index 0000000..da61357 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTClient.h @@ -0,0 +1,1945 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - remove const from eyecatchers #168 + *******************************************************************************/ + +/** + * @cond MQTTClient_internal + * @mainpage MQTT Client Library Internals + * In the beginning there was one MQTT C client library, MQTTClient, as implemented in MQTTClient.c + * This library was designed to be easy to use for applications which didn't mind if some of the calls + * blocked for a while. For instance, the MQTTClient_connect call will block until a successful + * connection has completed, or a connection has failed, which could be as long as the "connection + * timeout" interval, whose default is 30 seconds. + * + * However in mobile devices and other windowing environments, blocking on the GUI thread is a bad + * thing as it causes the user interface to freeze. Hence a new API, MQTTAsync, implemented + * in MQTTAsync.c, was devised. There are no blocking calls in this library, so it is well suited + * to GUI and mobile environments, at the expense of some extra complexity. + * + * Both libraries are designed to be sparing in the use of threads. So multiple client objects are + * handled by one or two threads, with a select call in Socket_getReadySocket(), used to determine + * when a socket has incoming data. This API is thread safe: functions may be called by multiple application + * threads, with the exception of ::MQTTClient_yield and ::MQTTClient_receive, which are intended + * for single threaded environments only. + * + * @endcond + * @cond MQTTClient_main + * @mainpage MQTT Client library for C + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An MQTT client library in C. + * + * These pages describe the original more synchronous API which might be + * considered easier to use. Some of the calls will block. For the new + * totally asynchronous API where no calls block, which is especially suitable + * for use in windowed environments, see the + * MQTT C Client Asynchronous API Documentation. + * The MQTTClient API is not thread safe, whereas the MQTTAsync API is. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions if multi-threaded (asynchronous mode) + * operation is being used (see @ref async).
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref pubsync
  • + *
  • @ref pubasync
  • + *
  • @ref subasync
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref callbacks
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENT_H) +#define MQTTCLIENT_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTCLIENT_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTCLIENT_FAILURE -1 + +/* error code -2 is MQTTCLIENT_PERSISTENCE_ERROR */ + +/** + * Return code: The client is disconnected. + */ +#define MQTTCLIENT_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTCLIENT_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTCLIENT_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTCLIENT_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTCLIENT_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTCLIENT_BAD_STRUCTURE -8 +/** + * Return code: A QoS value that falls outside of the acceptable range (0,1,2) + */ +#define MQTTCLIENT_BAD_QOS -9 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTCLIENT_SSL_NOT_SUPPORTED -10 + /** + * Return code: unrecognized MQTT version + */ + #define MQTTCLIENT_BAD_MQTT_VERSION -11 +/** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + */ +#define MQTTCLIENT_BAD_PROTOCOL -14 + /** + * Return code: option not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic on connect + */ + #define MQTTCLIENT_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 + /** + * MQTT version to connect with: 5 + */ + #define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTClient_init_options; + +#define MQTTClient_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library (0) + */ +LIBMQTT_API void MQTTClient_global_init(MQTTClient_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTClient_create(). + */ +typedef void* MQTTClient; +/** + * A value representing an MQTT message. A delivery token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTClient_publish(), + * MQTTClient_publishMessage(), + * MQTTClient_deliveryComplete(), + * MQTTClient_waitForCompletion() and + * MQTTClient_getPendingDeliveryTokens()). + */ +typedef int MQTTClient_deliveryToken; +typedef int MQTTClient_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTClient_publishMessage(), + * MQTTClient_publish(), MQTTClient_receive(), MQTTClient_freeMessage() + * and MQTTClient_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. + */ + int dup; + /** The message identifier is normally reserved for internal use by the + * MQTT client and server. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTClient_message; + +#define MQTTClient_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTClient_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTClient_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTClient_freeMessage must be called. + * To free the topic name storage, ::MQTTClient_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTClient_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTClient_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages. The function is registered with the + * client library by passing it as an argument to MQTTClient_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note:MQTTClient_deliveryComplete() is not called when messages are + * published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken dt); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTClient_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_connectionLost(void* context, char* cause); + +/** + * This function sets the callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Calling MQTTClient_setCallbacks() puts the + * client into multi-threaded mode. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. See @ref async for more information. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTClient_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTClient_messageArrived() callback + * function. This callback function must be set when you call + * MQTTClient_setCallbacks(), as otherwise there would be nowhere to deliver + * any incoming messages. + * @param dc A pointer to an MQTTClient_deliveryComplete() callback + * function. You can set this to NULL if your application publishes + * synchronously or if you do not want to check for successful delivery. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl, + MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc); + + +/** + * This is a callback function, which will be called when the a disconnect + * packet is received from the server. This applies to MQTT V5 and above only. + * @param context A pointer to the context value originally passed to + * ::MQTTClient_setDisconnected(), which contains any application-specific context. + * @param properties The MQTT V5 properties received with the disconnect, if any. + * @param reasonCode The MQTT V5 reason code received with the disconnect. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTClient_disconnected() callback function for a client. This will be called + * if a disconnect packet is received from the server. Only valid for MQTT V5 and above. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTClient_disconnected() callback + * function. NULL removes the callback setting. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setDisconnected(MQTTClient handle, void* context, MQTTClient_disconnected* co); + +/** + * This is a callback function, the MQTT V5 version of MQTTClient_deliveryComplete(). + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the completed delivery of messages. + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note: It is not called when messages are published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + * @param packet_type the last received packet type for this completion. For QoS 1 + * always PUBACK. For QoS 2 could be PUBREC or PUBCOMP. + * @param properties the MQTT V5 properties returned with the last packet from the server + * @param reasonCode the reason code returned from the server + */ +typedef void MQTTClient_published(void* context, int dt, int packet_type, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +LIBMQTT_API int MQTTClient_setPublished(MQTTClient handle, void* context, MQTTClient_published* co); + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTClient_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; +} MQTTClient_createOptions; + +#define MQTTClient_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, MQTTVERSION_DEFAULT } + +/** + * A version of :MQTTClient_create() with additional options. + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp or ssl. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @param options additional options for the create. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_createWithOptions(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTClient_createOptions* options); + +/** + * MQTTClient_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTClient_willOptions + * structure is passed in the MQTTClient_connectOptions structure used in the + * MQTTClient_connect() call that connects the client to the server. The pointer + * to MQTTClient_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 means there is no binary payload option + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload in string form. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTClient_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTClient_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTClient_willOptions; + +#define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTClient_SSLOptions; + +#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** + * MQTTClient_libraryInfo is used to store details relating to the currently used + * library such as the version in use, the time it was built and relevant openSSL + * options. + * There is one static instance of this struct in MQTTClient.c + */ + +typedef struct +{ + const char* name; + const char* value; +} MQTTClient_nameValue; + +/** + * This function returns version information about the library. + * no trace information will be returned. + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTClient_nameValue* MQTTClient_getVersionInfo(void); + +/** + * MQTTClient_connectOptions defines several settings that control the way the + * client connects to an MQTT server. + * + * Note: Default values are not defined for members of + * MQTTClient_connectOptions so it is good practice to specify all settings. + * If the MQTTClient_connectOptions structure is defined as an automatic + * variable, all members are set to random values and thus must be set by the + * client application. If the MQTTClient_connectOptions structure is defined + * as a static variable, initialization (in compliant compilers) sets all + * values to 0 (NULL for pointers). A #keepAliveInterval setting of 0 prevents + * correct operation of the client and so you must at least set a value + * for #keepAliveInterval. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3, 4, 5, 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no returned values + * 4 signifies no binary password option + * 5 signifies no maxInflightMessages and cleanstart + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTClient_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This is a boolean value that controls how many messages can be in-flight + * simultaneously. Setting reliable to true means that a published + * message must be completed (acknowledgements received) before another + * can be sent. Attempts to publish additional messages receive an + * ::MQTTCLIENT_MAX_MESSAGES_INFLIGHT return code. Setting this flag to + * false allows up to 10 messages to be in-flight. This can increase + * overall throughput in some circumstances. + */ + int reliable; + /** + * This is a pointer to an MQTTClient_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTClient_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTClient_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTClient_SSLOptions* ssl; + /** + * The number of entries in the optional serverURIs array. Defaults to 0. + */ + int serverURIcount; + /** + * An optional array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * If this list is empty (the default), the server URI specified on MQTTClient_create() + * is used. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + * MQTTVERSION_5 (5) = only try version 5.0 + */ + int MQTTVersion; + /** + * Returned from the connect when the MQTT version used to connect is 3.1.1 + */ + struct + { + const char* serverURI; /**< the serverURI connected to */ + int MQTTVersion; /**< the MQTT version used to connect with */ + int sessionPresent; /**< if the MQTT version is 3.1.1, the value of sessionPresent returned in the connack */ + } returned; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct + { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /** + * The maximum number of messages in flight + */ + int maxInflightMessages; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * HTTP headers for websockets + */ + const MQTTClient_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTClient_connectOptions; + +#define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +/** + * This function attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @return ::MQTTCLIENT_SUCCESS if the client successfully connects to the + * server. An error code is returned if the client was unable to connect to + * the server. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options); + +/** MQTT version 5.0 response information */ +typedef struct MQTTResponse +{ + int version; /* the version number of this structure */ + enum MQTTReasonCodes reasonCode; /* the MQTT 5.0 reason code returned */ + int reasonCodeCount; /* the number of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + enum MQTTReasonCodes* reasonCodes; /* a list of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + MQTTProperties* properties; /* optionally, the MQTT 5.0 properties returned */ +} MQTTResponse; + +#define MQTTResponse_initializer {1, MQTTREASONCODE_SUCCESS, 0, NULL, NULL} + +/** + * Frees the storage associated with the MQTT response. + * @param response the response structure to be freed + */ +LIBMQTT_API void MQTTResponse_free(MQTTResponse response); + +/** + * Attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using MQTT version 5.0 and the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @param connectProperties the MQTT 5.0 connect properties to use + * @param willProperties the MQTT 5.0 properties to set on the will message + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_connect5(MQTTClient handle, MQTTClient_connectOptions* options, + MQTTProperties* connectProperties, MQTTProperties* willProperties); + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTClient_connectOptions.cleansession and MQTTClient_connect()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param timeout The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTClient_disconnect(MQTTClient handle, int timeout); + +LIBMQTT_API int MQTTClient_disconnect5(MQTTClient handle, int timeout, enum MQTTReasonCodes reason, MQTTProperties* props); + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTClient_isConnected(MQTTClient handle); + + +/* Subscribe is synchronous. QoS list parameter is changed on return to granted QoSs. + Returns return code, MQTTCLIENT_SUCCESS == success, non-zero some sort of error (TBD) */ + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTClient_subscribe(MQTTClient handle, const char* topic, int qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribe5(MQTTClient handle, const char* topic, int qos, + MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribeMany5(MQTTClient handle, int count, char* const* topic, + int* qos, MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @return ::MQTTCLIENT_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTClient_unsubscribe(MQTTClient handle, const char* topic); + +/** + * This function attempts to remove an existing subscription made by the + * specified client using MQTT 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribe5(MQTTClient handle, const char* topic, MQTTProperties* props); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @return ::MQTTCLIENT_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client using MQTT version 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribeMany5(MQTTClient handle, int count, char* const* topic, MQTTProperties* props); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publishMessage()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publish(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, int qos, int retained, + MQTTClient_deliveryToken* dt); + +/** + * Attempts to publish a message to a given topic using MQTT version 5.0 (see also + * MQTTClient_publishMessage5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param properties the MQTT 5.0 properties to be used + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publish5(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, + int qos, int retained, MQTTProperties* properties, MQTTClient_deliveryToken* dt); +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publishMessage(MQTTClient handle, const char* topicName, MQTTClient_message* msg, MQTTClient_deliveryToken* dt); + + +/** + * Attempts to publish a message to the given topic using MQTT version 5.0 + * (see also + * MQTTClient_publish5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char* topicName, MQTTClient_message* msg, + MQTTClient_deliveryToken* dt); + +/** + * This function is called by the client application to synchronize execution + * of the main thread with completed publication of a message. When called, + * MQTTClient_waitForCompletion() blocks execution until the message has been + * successful delivered or the specified timeout has expired. See @ref async. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param dt The ::MQTTClient_deliveryToken that represents the message being + * tested for successful delivery. Delivery tokens are issued by the + * publishing functions MQTTClient_publish() and MQTTClient_publishMessage(). + * @param timeout The maximum time to wait in milliseconds. + * @return ::MQTTCLIENT_SUCCESS if the message was successfully delivered. + * An error code is returned if the timeout expires or there was a problem + * checking the token. + */ +LIBMQTT_API int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken dt, unsigned long timeout); + + +/** + * This function sets a pointer to an array of delivery tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param tokens The address of a pointer to an ::MQTTClient_deliveryToken. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTCLIENT_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTClient_getPendingDeliveryTokens(MQTTClient handle, MQTTClient_deliveryToken **tokens); + +/** + * When implementing a single-threaded client, call this function periodically + * to allow processing of message retries and to send MQTT keepalive pings. + * If the application is calling MQTTClient_receive() regularly, then it is + * not necessary to call this function. + */ +LIBMQTT_API void MQTTClient_yield(void); + +/** + * This function performs a synchronous receive of incoming messages. It should + * be used only when the client application has not set callback methods to + * support asynchronous receipt of messages (see @ref async and + * MQTTClient_setCallbacks()). Using this function allows a single-threaded + * client subscriber application to be written. When called, this function + * blocks until the next message arrives or the specified timeout expires + *(see also MQTTClient_yield()). + * + * Important note: The application must free() the memory allocated + * to the topic and the message when processing is complete (see + * MQTTClient_freeMessage()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The address of a pointer to a topic. This function + * allocates the memory for the topic and returns it to the application + * by setting topicName to point to the topic. + * @param topicLen The length of the topic. If the return code from this + * function is ::MQTTCLIENT_TOPICNAME_TRUNCATED, the topic contains embedded + * NULL characters and the full topic should be retrieved by using + * topicLen. + * @param message The address of a pointer to the received message. This + * function allocates the memory for the message and returns it to the + * application by setting message to point to the received message. + * The pointer is set to NULL if the timeout expires. + * @param timeout The length of time to wait for a message in milliseconds. + * @return ::MQTTCLIENT_SUCCESS or ::MQTTCLIENT_TOPICNAME_TRUNCATED if a + * message is received. ::MQTTCLIENT_SUCCESS can also indicate that the + * timeout expired, in which case message is NULL. An error code is + * returned if there was a problem trying to receive a message. + */ +LIBMQTT_API int MQTTClient_receive(MQTTClient handle, char** topicName, int* topicLen, MQTTClient_message** message, + unsigned long timeout); + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTClient_free() library function. + * @param msg The address of a pointer to the ::MQTTClient_message structure + * to be freed. + */ +LIBMQTT_API void MQTTClient_freeMessage(MQTTClient_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client libary and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTClient_free(void* ptr); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTClient_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTClient + * structure to be freed. + */ +LIBMQTT_API void MQTTClient_destroy(MQTTClient* handle); + + +enum MQTTCLIENT_TRACE_LEVELS +{ + MQTTCLIENT_TRACE_MAXIMUM = 1, + MQTTCLIENT_TRACE_MEDIUM, + MQTTCLIENT_TRACE_MINIMUM, + MQTTCLIENT_TRACE_PROTOCOL, + MQTTCLIENT_TRACE_ERROR, + MQTTCLIENT_TRACE_SEVERE, + MQTTCLIENT_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTClient_setTraceLevel(enum MQTTCLIENT_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTClient_traceCallback(enum MQTTCLIENT_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTClient_setTraceCallback(MQTTClient_traceCallback* callback); + +/** + * Sets the timeout value for un/subscribe commands when waiting for the un/suback response from + * the server. Values less than 5000 are not allowed. + * @param handle A valid client handle from a successful call to MQTTClient_create(). + * @param milliSeconds the maximum number of milliseconds to wait + * @return MQTTCLIENT_SUCCESS or MQTTCLIENT_FAILURE + */ +LIBMQTT_API int MQTTClient_setCommandTimeout(MQTTClient handle, unsigned long milliSeconds); + +/** + * Returns a pointer to the string representation of the error or NULL. + * + * Do not free after use. Returns NULL if the error code is unknown. + */ +LIBMQTT_API const char* MQTTClient_strerror(int code); + +#if defined(__cplusplus) + } +#endif + +#endif + +/*! + * @cond MQTTClient_main + * @page async Asynchronous vs synchronous client applications + * This client library supports two modes of operation. These are referred to + * as synchronous and asynchronous modes. If your application + * calls MQTTClient_setCallbacks(), this puts the client into asynchronous + * mode, otherwise it operates in synchronous mode. + * + * In synchronous mode, the client application runs on a single thread. + * Messages are published using the MQTTClient_publish() and + * MQTTClient_publishMessage() functions. To determine that a QoS1 or QoS2 + * (see @ref qos) message has been successfully delivered, the application + * must call the MQTTClient_waitForCompletion() function. An example showing + * synchronous publication is shown in @ref pubsync. Receiving messages in + * synchronous mode uses the MQTTClient_receive() function. Client applications + * must call either MQTTClient_receive() or MQTTClient_yield() relatively + * frequently in order to allow processing of acknowledgements and the MQTT + * "pings" that keep the network connection to the server alive. + * + * In asynchronous mode, the client application runs on several threads. The + * main program calls functions in the client library to publish and subscribe, + * just as for the synchronous mode. Processing of handshaking and maintaining + * the network connection is performed in the background, however. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTClient_setCallbacks() (see MQTTClient_messageArrived(), + * MQTTClient_connectionLost() and MQTTClient_deliveryComplete()). + * This API is not thread safe however - it is not possible to call it from multiple + * threads without synchronization. You can use the MQTTAsync API for that. + * + * @page callbacks Callbacks + * You must not call a function from this API from within a callback otherwise + * a deadlock might result. The only exception to this is the ability to call + * connect within the connection lost callback, to allow a reconnect. + * + * When using MQTT 5.0, you can also call connect from within the disconnected + * callback, which is invoked when the MQTT server sends a disconnect packet. + * This server behaviour is allowed in MQTT 5.0, but not in MQTT 3.1.1, so the + * disconnected callback will never be invoked if you use MQTT 3.1.1. + * + * In particular, you must make a publish call within the message arrived callback. + * These restrictions are all lifted in the + * MQTTAsync API. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, or receive not called, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * It is up to the application to protect against this situation. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTClient_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTClient_subscribe() and MQTTClient_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page pubsync Synchronous publication example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for up to %d seconds for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID); + rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); + printf("Message with delivery token %d delivered\n", token); + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + printf("Failed to disconnect, return code %d\n", rc); + MQTTClient_destroy(&client); + return rc; +} + + * @endcode + * + * @page pubasync Asynchronous publication example +@code{.c} +#include +#include +#include +#include "MQTTClient.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + deliveredtoken = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (deliveredtoken != token) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } + +destroy_exit: + MQTTClient_destroy(&client); + +exit: + return rc; +} + + * @endcode + * @page subasync Asynchronous subscription example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +volatile MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + if ((rc = MQTTClient_subscribe(client, TOPIC, QOS)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to subscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + int ch; + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + if ((rc = MQTTClient_unsubscribe(client, TOPIC)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to unsubscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } +destroy_exit: + MQTTClient_destroy(&client); +exit: + return rc; +} + + * @endcode + * @page tracing Tracing + * + * Runtime tracing is controlled by environment variables. + * + * Tracing is switched on by setting MQTT_C_CLIENT_TRACE. A value of ON, or stdout, prints to + * stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTClientPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTClientPersistence.h new file mode 100644 index 0000000..d3caae4 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTClientPersistence.h @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** + * @file + * \brief This structure represents a persistent data store, used to store + * outbound and inbound messages, in order to achieve reliable messaging. + * + * The MQTT Client persists QoS1 and QoS2 messages in order to meet the + * assurances of delivery associated with these @ref qos levels. The messages + * are saved in persistent storage + * The type and context of the persistence implementation are specified when + * the MQTT client is created (see MQTTClient_create()). The default + * persistence type (::MQTTCLIENT_PERSISTENCE_DEFAULT) uses a file system-based + * persistence mechanism. The persistence_context argument passed to + * MQTTClient_create() when using the default peristence is a string + * representing the location of the persistence directory. If the context + * argument is NULL, the working directory will be used. + * + * To use memory-based persistence, an application passes + * ::MQTTCLIENT_PERSISTENCE_NONE as the persistence_type to + * MQTTClient_create(). This can lead to message loss in certain situations, + * but can be appropriate in some cases (see @ref qos). + * + * Client applications can provide their own persistence mechanism by passing + * ::MQTTCLIENT_PERSISTENCE_USER as the persistence_type. To implement a + * custom persistence mechanism, the application must pass an initialized + * ::MQTTClient_persistence structure as the persistence_context + * argument to MQTTClient_create(). + * + * If the functions defined return an ::MQTTCLIENT_PERSISTENCE_ERROR then the + * state of the persisted data should remain as it was prior to the function + * being called. For example, if Persistence_put() returns + * ::MQTTCLIENT_PERSISTENCE_ERROR, then it is assumed tha tthe persistent store + * does not contain the data that was passed to the function. Similarly, if + * Persistence_remove() returns ::MQTTCLIENT_PERSISTENCE_ERROR then it is + * assumed that the data to be removed is still held in the persistent store. + * + * It is up to the persistence implementation to log any error information that + * may be required to diagnose a persistence mechanism failure. + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENTPERSISTENCE_H) +#define MQTTCLIENTPERSISTENCE_H +/* +/// @endcond +*/ + +/** + * This persistence_type value specifies the default file system-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_DEFAULT 0 +/** + * This persistence_type value specifies a memory-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_NONE 1 +/** + * This persistence_type value specifies an application-specific + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_USER 2 + +/** + * Application-specific persistence functions must return this error code if + * there is a problem executing the function. + */ +#define MQTTCLIENT_PERSISTENCE_ERROR -2 + +/** + * @brief Initialize the persistent store. + * + * Either open the existing persistent store for this client ID or create a new + * one if one doesn't exist. If the persistent store is already open, return + * without taking any action. + * + * An application can use the same client identifier to connect to many + * different servers. The clientid in conjunction with the + * serverURI uniquely identifies the persistence store required. + * + * @param handle The address of a pointer to a handle for this persistence + * implementation. This function must set handle to a valid reference to the + * persistence following a successful return. + * The handle pointer is passed as an argument to all the other + * persistence functions. It may include the context parameter and/or any other + * data for use by the persistence functions. + * @param clientID The client identifier for which the persistent store should + * be opened. + * @param serverURI The connection string specified when the MQTT client was + * created (see MQTTClient_create()). + * @param context A pointer to any data required to initialize the persistent + * store (see ::MQTTClient_persistence). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_open)(void** handle, const char* clientID, const char* serverURI, void* context); + +/** + * @brief Close the persistent store referred to by the handle. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_close)(void* handle); + +/** + * @brief Put the specified data into the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string used as the key for the data to be put in the store. The + * key is later used to retrieve data from the store with Persistence_get(). + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers associated with + * this key. + * @param buflens An array of lengths of the data buffers. buflen[n] + * gives the length of buffer[n]. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_put)(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); + +/** + * @brief Retrieve the specified data from the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be retrieved. This is + * the same key used to save the data to the store with Persistence_put(). + * @param buffer The address of a pointer to a buffer. This function sets the + * pointer to point at the retrieved data, if successful. + * @param buflen The address of an int that is set to the length of + * buffer by this function if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_get)(void* handle, char* key, char** buffer, int* buflen); + +/** + * @brief Remove the data for the specified key from the store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be removed from the + * store. This is the same key used to save the data to the store with + * Persistence_put(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_remove)(void* handle, char* key); + +/** + * @brief Returns the keys in this persistent data store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param keys The address of a pointer to pointers to strings. Assuming + * successful execution, this function allocates memory to hold the returned + * keys (strings used to store the data with Persistence_put()). It also + * allocates memory to hold an array of pointers to these strings. keys + * is set to point to the array of pointers to strings. + * @param nkeys A pointer to the number of keys in this persistent data store. + * This function sets the number of keys, if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_keys)(void* handle, char*** keys, int* nkeys); + +/** + * @brief Clears the persistence store, so that it no longer contains any + * persisted data. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_clear)(void* handle); + +/** + * @brief Returns whether any data has been persisted using the specified key. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key The string to be tested for existence in the store. + * @return Return 0 if the key was found in the store, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_containskey)(void* handle, char* key); + +/** + * @brief A structure containing the function pointers to a persistence + * implementation and the context or state that will be shared across all + * the persistence functions. + */ +typedef struct { + /** + * A pointer to any data required to initialize the persistent store. + */ + void* context; + /** + * A function pointer to an implementation of Persistence_open(). + */ + Persistence_open popen; + /** + * A function pointer to an implementation of Persistence_close(). + */ + Persistence_close pclose; + /** + * A function pointer to an implementation of Persistence_put(). + */ + Persistence_put pput; + /** + * A function pointer to an implementation of Persistence_get(). + */ + Persistence_get pget; + /** + * A function pointer to an implementation of Persistence_remove(). + */ + Persistence_remove premove; + /** + * A function pointer to an implementation of Persistence_keys(). + */ + Persistence_keys pkeys; + /** + * A function pointer to an implementation of Persistence_clear(). + */ + Persistence_clear pclear; + /** + * A function pointer to an implementation of Persistence_containskey(). + */ + Persistence_containskey pcontainskey; +} MQTTClient_persistence; + + +/** + * A callback which is invoked just before a write to persistence. This can be + * used to transform the data, for instance to encrypt it. + * @param context The context as set in ::MQTTAsync_setBeforePersistenceWrite + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers. + * @param buflens An array of lengths of the data buffers. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_beforeWrite(void* context, int bufcount, char* buffers[], int buflens[]); + + +/** + * A callback which is invoked just after a read from persistence. This can be + * used to transform the data, for instance to decrypt it. + * @param context The context as set in ::MQTTAsync_setAfterPersistenceRead + * @param buffer The address of a pointer to a buffer. + * @param buflen The address of an int that is the length of the buffer. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_afterRead(void* context, char** buffer, int* buflen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTExportDeclarations.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTExportDeclarations.h new file mode 100644 index 0000000..d492ef1 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTExportDeclarations.h @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 Andreas Walter + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Andreas Walter - initially moved export declarations into separate fle + *******************************************************************************/ + +#if !defined(EXPORTDECLARATIONS_H) +#define EXPORTDECLARATIONS_H + +#if defined(_WIN32) || defined(_WIN64) +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __declspec(dllexport) +# elif defined(PAHO_MQTT_IMPORTS) +# define LIBMQTT_API __declspec(dllimport) +# else +# define LIBMQTT_API +# endif +#else +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __attribute__ ((visibility ("default"))) +# else +# define LIBMQTT_API extern +# endif +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPacket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPacket.h new file mode 100644 index 0000000..658404a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPacket.h @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - big endian Linux reversed definition + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKET_H) +#define MQTTPACKET_H + +#include "Socket.h" +#if defined(OPENSSL) +#include "SSLSocket.h" +#endif +#include "LinkedList.h" +#include "Clients.h" + +typedef unsigned int bool; +typedef void* (*pf)(int, unsigned char, char*, size_t); + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" + +enum errors +{ + MQTTPACKET_BAD = -4, + MQTTPACKET_BUFFER_TOO_SHORT = -2, + MQTTPACKET_READ_ERROR = -1, + MQTTPACKET_READ_COMPLETE +}; + + +enum msgTypes +{ + CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, + PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, + PINGREQ, PINGRESP, DISCONNECT, AUTH +}; + +#if defined(__linux__) +#include +#if __BYTE_ORDER == __BIG_ENDIAN + #define REVERSED 1 +#endif +#endif + +/** + * Bitfields for the MQTT header byte. + */ +typedef union +{ + /*unsigned*/ char byte; /**< the whole byte */ +#if defined(REVERSED) + struct + { + unsigned int type : 4; /**< message type nibble */ + bool dup : 1; /**< DUP flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool retain : 1; /**< retained flag bit */ + } bits; +#else + struct + { + bool retain : 1; /**< retained flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool dup : 1; /**< DUP flag bit */ + unsigned int type : 4; /**< message type nibble */ + } bits; +#endif +} Header; + + +/** + * Data for a connect packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connect flags */ +#if defined(REVERSED) + struct + { + bool username : 1; /**< 3.1 user name */ + bool password : 1; /**< 3.1 password */ + bool willRetain : 1; /**< will retain setting */ + unsigned int willQoS : 2; /**< will QoS value */ + bool will : 1; /**< will flag */ + bool cleanstart : 1; /**< cleansession flag */ + int : 1; /**< unused */ + } bits; +#else + struct + { + int : 1; /**< unused */ + bool cleanstart : 1; /**< cleansession flag */ + bool will : 1; /**< will flag */ + unsigned int willQoS : 2; /**< will QoS value */ + bool willRetain : 1; /**< will retain setting */ + bool password : 1; /**< 3.1 password */ + bool username : 1; /**< 3.1 user name */ + } bits; +#endif + } flags; /**< connect flags byte */ + + char *Protocol, /**< MQTT protocol name */ + *clientID, /**< string client id */ + *willTopic, /**< will topic */ + *willMsg; /**< will payload */ + + int keepAliveTimer; /**< keepalive timeout value in seconds */ + unsigned char version; /**< MQTT version number */ +} Connect; + + +/** + * Data for a connack packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connack flags */ +#if defined(REVERSED) + struct + { + unsigned int reserved : 7; /**< message type nibble */ + bool sessionPresent : 1; /**< was a session found on the server? */ + } bits; +#else + struct + { + bool sessionPresent : 1; /**< was a session found on the server? */ + unsigned int reserved : 7; /**< message type nibble */ + } bits; +#endif + } flags; /**< connack flags byte */ + unsigned char rc; /**< connack reason code */ + unsigned int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Connack; + + +/** + * Data for a packet with header only. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ +} MQTTPacket; + + +/** + * Data for a suback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* qoss; /**< list of granted QoSs (MQTT 3/4) / reason codes (MQTT 5) */ +} Suback; + + +/** + * Data for an MQTT V5 unsuback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* reasonCodes; /**< list of reason codes */ +} Unsuback; + + +/** + * Data for a publish packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + char* topic; /**< topic string */ + int topiclen; + int msgId; /**< MQTT message id */ + char* payload; /**< binary payload, length delimited */ + int payloadlen; /**< payload length */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + uint8_t mask[4]; /**< the websockets mask the payload is masked with, if any */ +} Publish; + + +/** + * Data for one of the ack packets. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + unsigned char rc; /**< MQTT 5 reason code */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Ack; + +typedef Ack Puback; +typedef Ack Pubrec; +typedef Ack Pubrel; +typedef Ack Pubcomp; + +int MQTTPacket_encode(char* buf, size_t length); +int MQTTPacket_decode(networkHandles* net, size_t* value); +int readInt(char** pptr); +char* readUTF(char** pptr, char* enddata); +unsigned char readChar(char** pptr); +void writeChar(char** pptr, char c); +void writeInt(char** pptr, int anInt); +void writeUTF(char** pptr, const char* string); +void writeData(char** pptr, const void* data, int datalen); + +const char* MQTTPacket_name(int ptype); + +void* MQTTPacket_Factory(int MQTTVersion, networkHandles* net, int* error); +int MQTTPacket_send(networkHandles* net, Header header, char* buffer, size_t buflen, int free, int MQTTVersion); +int MQTTPacket_sends(networkHandles* net, Header header, PacketBuffers* buffers, int MQTTVersion); + +void* MQTTPacket_header_only(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +int MQTTPacket_send_disconnect(Clients* client, enum MQTTReasonCodes reason, MQTTProperties* props); + +void* MQTTPacket_publish(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freePublish(Publish* pack); +int MQTTPacket_send_publish(Publish* pack, int dup, int qos, int retained, networkHandles* net, const char* clientID); +int MQTTPacket_send_puback(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +void MQTTPacket_freeAck(Ack* pack); +void MQTTPacket_freeSuback(Suback* pack); +void MQTTPacket_freeUnsuback(Unsuback* pack); +int MQTTPacket_send_pubrec(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubrel(int MQTTVersion, int msgid, int dup, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubcomp(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); + +void MQTTPacket_free_packet(MQTTPacket* pack); + +void writeInt4(char** pptr, int anInt); +int readInt4(char** pptr); +void writeMQTTLenString(char** pptr, MQTTLenString lenstring); +int MQTTLenStringRead(MQTTLenString* lenstring, char** pptr, char* enddata); +int MQTTPacket_VBIlen(int rem_len); +int MQTTPacket_decodeBuf(char* buf, unsigned int* value); + +#include "MQTTPacketOut.h" + +#endif /* MQTTPACKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPacketOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPacketOut.h new file mode 100644 index 0000000..d962554 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPacketOut.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKETOUT_H) +#define MQTTPACKETOUT_H + +#include "MQTTPacket.h" + +int MQTTPacket_send_connect(Clients* client, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +void* MQTTPacket_connack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freeConnack(Connack* pack); + +int MQTTPacket_send_pingreq(networkHandles* net, const char* clientID); + +int MQTTPacket_send_subscribe(List* topics, List* qoss, MQTTSubscribe_options* opts, MQTTProperties* props, + int msgid, int dup, Clients* client); +void* MQTTPacket_suback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +int MQTTPacket_send_unsubscribe(List* topics, MQTTProperties* props, int msgid, int dup, Clients* client); +void* MQTTPacket_unsuback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPersistence.h new file mode 100644 index 0000000..ed2e0ce --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPersistence.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - async client updates + * Ian Craggs - fix for bug 432903 - queue persistence + * Ian Craggs - MQTT V5 updates + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCE_H) +#define MQTTPERSISTENCE_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include "Clients.h" +#include "MQTTProperties.h" + +/** Stem of the key for a sent PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_PUBLISH_SENT "s-" +/** Stem of the key for a sent PUBREL */ +#define PERSISTENCE_PUBREL "sc-" +/** Stem of the key for a received PUBLISH QoS2 */ +#define PERSISTENCE_PUBLISH_RECEIVED "r-" + +/** Stem of the key for a sent MQTT V5 PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_V5_PUBLISH_SENT "s5-" +/** Stem of the key for a sent MQTT V5 PUBREL */ +#define PERSISTENCE_V5_PUBREL "sc5-" +/** Stem of the key for a received MQTT V5 PUBLISH QoS2 */ +#define PERSISTENCE_V5_PUBLISH_RECEIVED "r5-" + +/** Stem of the key for an async client command */ +#define PERSISTENCE_COMMAND_KEY "c-" +/** Stem of the key for an MQTT V5 async client command */ +#define PERSISTENCE_V5_COMMAND_KEY "c5-" +/** Stem of the key for an client incoming message queue */ +#define PERSISTENCE_QUEUE_KEY "q-" +/** Stem of the key for an MQTT V5 incoming message queue */ +#define PERSISTENCE_V5_QUEUE_KEY "q5-" +/** Maximum length of a stem for a persistence key */ +#define PERSISTENCE_MAX_STEM_LENGTH 3 +/** Maximum allowed length of a persistence key */ +#define PERSISTENCE_MAX_KEY_LENGTH 9 +/** Maximum size of an integer sequence number appended to a persistence key */ +#define PERSISTENCE_SEQNO_LIMIT 1000000 /*10^(PERSISTENCE_MAX_KEY_LENGTH - PERSISTENCE_MAX_STEM_LENGTH)*/ + +int MQTTPersistence_create(MQTTClient_persistence** per, int type, void* pcontext); +int MQTTPersistence_initialize(Clients* c, const char* serverURI); +int MQTTPersistence_close(Clients* c); +int MQTTPersistence_clear(Clients* c); +int MQTTPersistence_restorePackets(Clients* c); +void* MQTTPersistence_restorePacket(int MQTTVersion, char* buffer, size_t buflen); +void MQTTPersistence_insertInOrder(List* list, void* content, size_t size); +int MQTTPersistence_putPacket(int socket, char* buf0, size_t buf0len, int count, + char** buffers, size_t* buflens, int htype, int msgId, int scr, int MQTTVersion); +int MQTTPersistence_remove(Clients* c, char* type, int qos, int msgId); +void MQTTPersistence_wrapMsgID(Clients *c); + +typedef struct +{ + char struct_id[4]; + int struct_version; + int payloadlen; + void* payload; + int qos; + int retained; + int dup; + int msgid; + MQTTProperties properties; +} MQTTPersistence_message; + +typedef struct +{ + MQTTPersistence_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} MQTTPersistence_qEntry; + +int MQTTPersistence_unpersistQueueEntry(Clients* client, MQTTPersistence_qEntry* qe); +int MQTTPersistence_persistQueueEntry(Clients* aclient, MQTTPersistence_qEntry* qe); +int MQTTPersistence_restoreMessageQueue(Clients* c); +#ifdef __cplusplus + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPersistenceDefault.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPersistenceDefault.h new file mode 100644 index 0000000..506b4da --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTPersistenceDefault.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCEDEFAULT_H) +#define MQTTPERSISTENCEDEFAULT_H + +/** 8.3 filesystem */ +#define MESSAGE_FILENAME_LENGTH 8 +/** Extension of the filename */ +#define MESSAGE_FILENAME_EXTENSION ".msg" + +/* prototypes of the functions for the default file system persistence */ +int pstopen(void** handle, const char* clientID, const char* serverURI, void* context); +int pstclose(void* handle); +int pstput(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); +int pstget(void* handle, char* key, char** buffer, int* buflen); +int pstremove(void* handle, char* key); +int pstkeys(void* handle, char*** keys, int* nkeys); +int pstclear(void* handle); +int pstcontainskey(void* handle, char* key); + +int pstmkdir(char *pPathname); + +#endif + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProperties.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProperties.h new file mode 100644 index 0000000..81b8e3a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProperties.h @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPROPERTIES_H) +#define MQTTPROPERTIES_H + +#include "MQTTExportDeclarations.h" + +#define MQTT_INVALID_PROPERTY_ID -2 + +/** The one byte MQTT V5 property indicator */ +enum MQTTPropertyCodes { + MQTTPROPERTY_CODE_PAYLOAD_FORMAT_INDICATOR = 1, /**< The value is 1 */ + MQTTPROPERTY_CODE_MESSAGE_EXPIRY_INTERVAL = 2, /**< The value is 2 */ + MQTTPROPERTY_CODE_CONTENT_TYPE = 3, /**< The value is 3 */ + MQTTPROPERTY_CODE_RESPONSE_TOPIC = 8, /**< The value is 8 */ + MQTTPROPERTY_CODE_CORRELATION_DATA = 9, /**< The value is 9 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIER = 11, /**< The value is 11 */ + MQTTPROPERTY_CODE_SESSION_EXPIRY_INTERVAL = 17, /**< The value is 17 */ + MQTTPROPERTY_CODE_ASSIGNED_CLIENT_IDENTIFER = 18,/**< The value is 18 */ + MQTTPROPERTY_CODE_SERVER_KEEP_ALIVE = 19, /**< The value is 19 */ + MQTTPROPERTY_CODE_AUTHENTICATION_METHOD = 21, /**< The value is 21 */ + MQTTPROPERTY_CODE_AUTHENTICATION_DATA = 22, /**< The value is 22 */ + MQTTPROPERTY_CODE_REQUEST_PROBLEM_INFORMATION = 23,/**< The value is 23 */ + MQTTPROPERTY_CODE_WILL_DELAY_INTERVAL = 24, /**< The value is 24 */ + MQTTPROPERTY_CODE_REQUEST_RESPONSE_INFORMATION = 25,/**< The value is 25 */ + MQTTPROPERTY_CODE_RESPONSE_INFORMATION = 26, /**< The value is 26 */ + MQTTPROPERTY_CODE_SERVER_REFERENCE = 28, /**< The value is 28 */ + MQTTPROPERTY_CODE_REASON_STRING = 31, /**< The value is 31 */ + MQTTPROPERTY_CODE_RECEIVE_MAXIMUM = 33, /**< The value is 33*/ + MQTTPROPERTY_CODE_TOPIC_ALIAS_MAXIMUM = 34, /**< The value is 34 */ + MQTTPROPERTY_CODE_TOPIC_ALIAS = 35, /**< The value is 35 */ + MQTTPROPERTY_CODE_MAXIMUM_QOS = 36, /**< The value is 36 */ + MQTTPROPERTY_CODE_RETAIN_AVAILABLE = 37, /**< The value is 37 */ + MQTTPROPERTY_CODE_USER_PROPERTY = 38, /**< The value is 38 */ + MQTTPROPERTY_CODE_MAXIMUM_PACKET_SIZE = 39, /**< The value is 39 */ + MQTTPROPERTY_CODE_WILDCARD_SUBSCRIPTION_AVAILABLE = 40,/**< The value is 40 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIERS_AVAILABLE = 41,/**< The value is 41 */ + MQTTPROPERTY_CODE_SHARED_SUBSCRIPTION_AVAILABLE = 42/**< The value is 241 */ +}; + +/** + * Returns a printable string description of an MQTT V5 property code. + * @param value an MQTT V5 property code. + * @return the printable string description of the input property code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTPropertyName(enum MQTTPropertyCodes value); + +/** The one byte MQTT V5 property type */ +enum MQTTPropertyTypes { + MQTTPROPERTY_TYPE_BYTE, + MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER, + MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER, + MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER, + MQTTPROPERTY_TYPE_BINARY_DATA, + MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING, + MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR +}; + +/** + * Returns the MQTT V5 type code of an MQTT V5 property. + * @param value an MQTT V5 property code. + * @return the MQTT V5 type code of the input property. -1 if the code was not found. + */ +LIBMQTT_API int MQTTProperty_getType(enum MQTTPropertyCodes value); + +/** + * The data for a length delimited string + */ +typedef struct +{ + int len; /**< the length of the string */ + char* data; /**< pointer to the string data */ +} MQTTLenString; + + +/** + * Structure to hold an MQTT version 5 property of any type + */ +typedef struct +{ + enum MQTTPropertyCodes identifier; /**< The MQTT V5 property id. A multi-byte integer. */ + /** The value of the property, as a union of the different possible types. */ + union { + unsigned char byte; /**< holds the value of a byte property type */ + unsigned short integer2; /**< holds the value of a 2 byte integer property type */ + unsigned int integer4; /**< holds the value of a 4 byte integer property type */ + struct { + MQTTLenString data; /**< The value of a string property, or the name of a user property. */ + MQTTLenString value; /**< The value of a user property. */ + }; + } value; +} MQTTProperty; + +/** + * MQTT version 5 property list + */ +typedef struct MQTTProperties +{ + int count; /**< number of property entries in the array */ + int max_count; /**< max number of properties that the currently allocated array can store */ + int length; /**< mbi: byte length of all properties */ + MQTTProperty *array; /**< array of properties */ +} MQTTProperties; + +#define MQTTProperties_initializer {0, 0, 0, NULL} + +/** + * Returns the length of the properties structure when serialized ready for network transmission. + * @param props an MQTT V5 property structure. + * @return the length in bytes of the properties when serialized. + */ +int MQTTProperties_len(MQTTProperties* props); + +/** + * Add a property pointer to the property array. There is no memory allocation. + * @param props The property list to add the property to. + * @param prop The property to add to the list. + * @return 0 on success, -1 on failure. + */ +LIBMQTT_API int MQTTProperties_add(MQTTProperties* props, const MQTTProperty* prop); + +/** + * Serialize the given property list to a character buffer, e.g. for writing to the network. + * @param pptr pointer to the buffer - move the pointer as we add data + * @param properties pointer to the property list, can be NULL + * @return whether the write succeeded or not: number of bytes written, or < 0 on failure. + */ +int MQTTProperties_write(char** pptr, const MQTTProperties* properties); + +/** + * Reads a property list from a character buffer into an array. + * @param properties pointer to the property list to be filled. Should be initalized but empty. + * @param pptr pointer to the character buffer. + * @param enddata pointer to the end of the character buffer so we don't read beyond. + * @return 1 if the properties were read successfully. + */ +int MQTTProperties_read(MQTTProperties* properties, char** pptr, char* enddata); + +/** + * Free all memory allocated to the property list, including any to individual properties. + * @param properties pointer to the property list. + */ +LIBMQTT_API void MQTTProperties_free(MQTTProperties* properties); + +/** + * Copy the contents of a property list, allocating additional memory if needed. + * @param props pointer to the property list. + * @return the duplicated property list. + */ +LIBMQTT_API MQTTProperties MQTTProperties_copy(const MQTTProperties* props); + +/** + * Checks if property list contains a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return 1 if found, 0 if not. + */ +LIBMQTT_API int MQTTProperties_hasProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the number of instances of a property id. Most properties can exist only once. + * User properties and subscription ids can exist more than once. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the number of times found. Can be 0. + */ +LIBMQTT_API int MQTTProperties_propertyCount(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property. The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValue(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property when it's not the only instance. + * The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValueAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +/** + * Returns a pointer to the property structure for a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns a pointer to the property structure for a specific property when it's not the only instance. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getPropertyAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +#endif /* MQTTPROPERTIES_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProtocol.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProtocol.h new file mode 100644 index 0000000..52bcd15 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProtocol.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - MQTT 3.1.1 updates + *******************************************************************************/ + +#if !defined(MQTTPROTOCOL_H) +#define MQTTPROTOCOL_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +typedef struct +{ + int socket; + Publications* p; +} pending_write; + + +typedef struct +{ + List publications; + unsigned int msgs_received; + unsigned int msgs_sent; + List pending_writes; /* for qos 0 writes not complete */ +} MQTTProtocol; + + +#include "MQTTProtocolOut.h" + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProtocolClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProtocolClient.h new file mode 100644 index 0000000..2d077af --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProtocolClient.h @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 updates + * Rong Xiang, Ian Craggs - C++ compatibility + * Ian Craggs - add debug definition of MQTTStrdup for when needed + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLCLIENT_H) +#define MQTTPROTOCOLCLIENT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Log.h" +#include "MQTTProtocol.h" +#include "Messages.h" +#include "MQTTProperties.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +int MQTTProtocol_startPublish(Clients* pubclient, Publish* publish, int qos, int retained, Messages** m); +Messages* MQTTProtocol_createMessage(Publish* publish, Messages** mm, int qos, int retained, int allocatePayload); +Publications* MQTTProtocol_storePublication(Publish* publish, int* len); +int messageIDCompare(void* a, void* b); +int MQTTProtocol_assignMsgId(Clients* client); +void MQTTProtocol_removePublication(Publications* p); +void Protocol_processPublication(Publish* publish, Clients* client, int allocatePayload); + +int MQTTProtocol_handlePublishes(void* pack, int sock); +int MQTTProtocol_handlePubacks(void* pack, int sock); +int MQTTProtocol_handlePubrecs(void* pack, int sock); +int MQTTProtocol_handlePubrels(void* pack, int sock); +int MQTTProtocol_handlePubcomps(void* pack, int sock); + +void MQTTProtocol_closeSession(Clients* c, int sendwill); +void MQTTProtocol_keepalive(START_TIME_TYPE); +void MQTTProtocol_retry(START_TIME_TYPE, int, int); +void MQTTProtocol_freeClient(Clients* client); +void MQTTProtocol_emptyMessageList(List* msgList); +void MQTTProtocol_freeMessageList(List* msgList); + +char* MQTTStrncpy(char *dest, const char* src, size_t num); +char* MQTTStrdup(const char* src); + +//#define MQTTStrdup(src) MQTTStrncpy(malloc(strlen(src)+1), src, strlen(src)+1) + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProtocolOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProtocolOut.h new file mode 100644 index 0000000..6a50155 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTProtocolOut.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - SNI support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLOUT_H) +#define MQTTPROTOCOLOUT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" +#include "Log.h" +#include "Messages.h" +#include "MQTTProtocol.h" +#include "MQTTProtocolClient.h" + +#define MQTT_DEFAULT_PORT 1883 +#define SECURE_MQTT_DEFAULT_PORT 8883 +#define WS_DEFAULT_PORT 80 + +size_t MQTTProtocol_addressPort(const char* uri, int* port, const char **topic, int default_port); +void MQTTProtocol_reconnect(const char* ip_address, Clients* client); +#if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#else +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#endif +int MQTTProtocol_handlePingresps(void* pack, int sock); +int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, int msgID, + MQTTSubscribe_options* opts, MQTTProperties* props); +int MQTTProtocol_handleSubacks(void* pack, int sock); +int MQTTProtocol_unsubscribe(Clients* client, List* topics, int msgID, MQTTProperties* props); +int MQTTProtocol_handleUnsubacks(void* pack, int sock); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTReasonCodes.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTReasonCodes.h new file mode 100644 index 0000000..2dc08ea --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTReasonCodes.h @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTREASONCODES_H) +#define MQTTREASONCODES_H + +#include "MQTTExportDeclarations.h" + +/** The MQTT V5 one byte reason code */ +enum MQTTReasonCodes { + MQTTREASONCODE_SUCCESS = 0, + MQTTREASONCODE_NORMAL_DISCONNECTION = 0, + MQTTREASONCODE_GRANTED_QOS_0 = 0, + MQTTREASONCODE_GRANTED_QOS_1 = 1, + MQTTREASONCODE_GRANTED_QOS_2 = 2, + MQTTREASONCODE_DISCONNECT_WITH_WILL_MESSAGE = 4, + MQTTREASONCODE_NO_MATCHING_SUBSCRIBERS = 16, + MQTTREASONCODE_NO_SUBSCRIPTION_FOUND = 17, + MQTTREASONCODE_CONTINUE_AUTHENTICATION = 24, + MQTTREASONCODE_RE_AUTHENTICATE = 25, + MQTTREASONCODE_UNSPECIFIED_ERROR = 128, + MQTTREASONCODE_MALFORMED_PACKET = 129, + MQTTREASONCODE_PROTOCOL_ERROR = 130, + MQTTREASONCODE_IMPLEMENTATION_SPECIFIC_ERROR = 131, + MQTTREASONCODE_UNSUPPORTED_PROTOCOL_VERSION = 132, + MQTTREASONCODE_CLIENT_IDENTIFIER_NOT_VALID = 133, + MQTTREASONCODE_BAD_USER_NAME_OR_PASSWORD = 134, + MQTTREASONCODE_NOT_AUTHORIZED = 135, + MQTTREASONCODE_SERVER_UNAVAILABLE = 136, + MQTTREASONCODE_SERVER_BUSY = 137, + MQTTREASONCODE_BANNED = 138, + MQTTREASONCODE_SERVER_SHUTTING_DOWN = 139, + MQTTREASONCODE_BAD_AUTHENTICATION_METHOD = 140, + MQTTREASONCODE_KEEP_ALIVE_TIMEOUT = 141, + MQTTREASONCODE_SESSION_TAKEN_OVER = 142, + MQTTREASONCODE_TOPIC_FILTER_INVALID = 143, + MQTTREASONCODE_TOPIC_NAME_INVALID = 144, + MQTTREASONCODE_PACKET_IDENTIFIER_IN_USE = 145, + MQTTREASONCODE_PACKET_IDENTIFIER_NOT_FOUND = 146, + MQTTREASONCODE_RECEIVE_MAXIMUM_EXCEEDED = 147, + MQTTREASONCODE_TOPIC_ALIAS_INVALID = 148, + MQTTREASONCODE_PACKET_TOO_LARGE = 149, + MQTTREASONCODE_MESSAGE_RATE_TOO_HIGH = 150, + MQTTREASONCODE_QUOTA_EXCEEDED = 151, + MQTTREASONCODE_ADMINISTRATIVE_ACTION = 152, + MQTTREASONCODE_PAYLOAD_FORMAT_INVALID = 153, + MQTTREASONCODE_RETAIN_NOT_SUPPORTED = 154, + MQTTREASONCODE_QOS_NOT_SUPPORTED = 155, + MQTTREASONCODE_USE_ANOTHER_SERVER = 156, + MQTTREASONCODE_SERVER_MOVED = 157, + MQTTREASONCODE_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158, + MQTTREASONCODE_CONNECTION_RATE_EXCEEDED = 159, + MQTTREASONCODE_MAXIMUM_CONNECT_TIME = 160, + MQTTREASONCODE_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161, + MQTTREASONCODE_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162 +}; + +/** + * Returns a printable string description of an MQTT V5 reason code. + * @param value an MQTT V5 reason code. + * @return the printable string description of the input reason code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTReasonCode_toString(enum MQTTReasonCodes value); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTSubscribeOpts.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTSubscribeOpts.h new file mode 100644 index 0000000..264e4d0 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTSubscribeOpts.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(SUBOPTS_H) +#define SUBOPTS_H + +/** The MQTT V5 subscribe options, apart from QoS which existed before V5. */ +typedef struct MQTTSubscribe_options +{ + /** The eyecatcher for this structure. Must be MQSO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0. + */ + int struct_version; + /** To not receive our own publications, set to 1. + * 0 is the original MQTT behaviour - all messages matching the subscription are received. + */ + unsigned char noLocal; + /** To keep the retain flag as on the original publish message, set to 1. + * If 0, defaults to the original MQTT behaviour where the retain flag is only set on + * publications sent by a broker if in response to a subscribe request. + */ + unsigned char retainAsPublished; + /** 0 - send retained messages at the time of the subscribe (original MQTT behaviour) + * 1 - send retained messages on subscribe only if the subscription is new + * 2 - do not send retained messages at all + */ + unsigned char retainHandling; +} MQTTSubscribe_options; + +#define MQTTSubscribe_options_initializer { {'M', 'Q', 'S', 'O'}, 0, 0, 0, 0 } + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTTime.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTTime.h new file mode 100644 index 0000000..8bd6860 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/MQTTTime.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + *******************************************************************************/ + +#if !defined(MQTTTIME_H) +#define MQTTTIME_H + +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#if WINVER >= _WIN32_WINNT_VISTA +#define START_TIME_TYPE ULONGLONG +#define START_TIME_ZERO 0 +#else +#define START_TIME_TYPE DWORD +#define START_TIME_ZERO 0 +#endif +#elif defined(AIX) +#define START_TIME_TYPE struct timespec +#define START_TIME_ZERO {0, 0} +#else +#include +#define START_TIME_TYPE struct timeval +#define START_TIME_ZERO {0, 0} +#endif + +#define ELAPSED_TIME_TYPE uint64_t +#define DIFF_TIME_TYPE int64_t + +void MQTTTime_sleep(ELAPSED_TIME_TYPE milliseconds); +START_TIME_TYPE MQTTTime_start_clock(void); +START_TIME_TYPE MQTTTime_now(void); +ELAPSED_TIME_TYPE MQTTTime_elapsed(START_TIME_TYPE milliseconds); +DIFF_TIME_TYPE MQTTTime_difftime(START_TIME_TYPE new, START_TIME_TYPE old); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Messages.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Messages.h new file mode 100644 index 0000000..58f5eae --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Messages.h @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MESSAGES_H) +#define MESSAGES_H + +#include "Log.h" + +const char* Messages_get(int, enum LOG_LEVELS); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/OsWrapper.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/OsWrapper.h new file mode 100644 index 0000000..96b629d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/OsWrapper.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016, 2017 logi.cals GmbH + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Gunter Raidl - timer support for VxWorks + * Rainer Poisel - reusability + *******************************************************************************/ + +#if !defined(OSWRAPPER_H) +#define OSWRAPPER_H + +#if defined(_WRS_KERNEL) +#include + +#define lstat stat + +typedef unsigned long useconds_t; +void usleep(useconds_t useconds); + +#define timersub(a, b, result) \ + do \ + { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) \ + { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000L; \ + } \ + } while (0) +#endif /* defined(_WRS_KERNEL) */ + +#endif /* OSWRAPPER_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/SHA1.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/SHA1.h new file mode 100644 index 0000000..3ae2f0a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/SHA1.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2018, 2019 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(SHA1_H) +#define SHA1_H + +#if defined(OPENSSL) +#include + +/** SHA-1 Digest Length */ +#define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH + +#else /* if defined(OPENSSL) */ + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +typedef struct SHA_CTX_S +{ + HCRYPTPROV hProv; + HCRYPTHASH hHash; +} SHA_CTX; +#else /* if defined(_WIN32) || defined(_WIN64) */ + +#include +typedef struct SHA_CTX_S { + uint32_t h[5]; + union { + uint32_t w[16]; + uint8_t buffer[64]; + }; + unsigned int size; + unsigned int total; +} SHA_CTX; +#endif /* else if defined(_WIN32) || defined(_WIN64) */ + +#include + +/** SHA-1 Digest Length (number of bytes in SHA1) */ +#define SHA1_DIGEST_LENGTH (160/8) + +/** + * Initializes the SHA1 hashing algorithm + * + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Update + * @see SHA1_Final + */ +int SHA1_Init(SHA_CTX *ctx); + +/** + * Updates a block to the SHA1 hash + * + * @param[in,out] ctx hashing context structure + * @param[in] data block of data to hash + * @param[in] len length of block to hash + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Update(SHA_CTX *ctx, const void *data, size_t len); + +/** + * Produce final SHA1 hash + * + * @param[out] md SHA1 hash produced (must be atleast + * @p SHA1_DIGEST_LENGTH in length) + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Final(unsigned char *md, SHA_CTX *ctx); + +#endif /* if defined(OPENSSL) */ +#endif /* SHA1_H */ + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/SSLSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/SSLSocket.h new file mode 100644 index 0000000..86273c8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/SSLSocket.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs, Allan Stockdill-Mander - initial implementation + * Ian Craggs - SNI support + * Ian Craggs - post connect checks and CApath + *******************************************************************************/ +#if !defined(SSLSOCKET_H) +#define SSLSOCKET_H + +#if defined(_WIN32) || defined(_WIN64) + #define ssl_mutex_type HANDLE +#else + #include + #include + #define ssl_mutex_type pthread_mutex_t +#endif + +#include +#include "SocketBuffer.h" +#include "Clients.h" + +#define URI_SSL "ssl://" + +/** if we should handle openssl initialization (bool_value == 1) or depend on it to be initalized externally (bool_value == 0) */ +void SSLSocket_handleOpensslInit(int bool_value); + +int SSLSocket_initialize(void); +void SSLSocket_terminate(void); +int SSLSocket_setSocketForSSL(networkHandles* net, MQTTClient_SSLOptions* opts, const char* hostname, size_t hostname_len); + +int SSLSocket_getch(SSL* ssl, int socket, char* c); +char *SSLSocket_getdata(SSL* ssl, int socket, size_t bytes, size_t* actual_len, int* rc); + +int SSLSocket_close(networkHandles* net); +int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +int SSLSocket_connect(SSL* ssl, int sock, const char* hostname, int verify, int (*cb)(const char *str, size_t len, void *u), void* u); + +int SSLSocket_getPendingRead(void); +int SSLSocket_continueWrite(pending_writes* pw); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Socket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Socket.h new file mode 100644 index 0000000..39a8158 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Socket.h @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + * Ian Craggs - async client updates + *******************************************************************************/ + +#if !defined(SOCKET_H) +#define SOCKET_H + +#include +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#include +#define MAXHOSTNAMELEN 256 +#if !defined(SSLSOCKET_H) +#undef EAGAIN +#define EAGAIN WSAEWOULDBLOCK +#undef EINTR +#define EINTR WSAEINTR +#undef EINPROGRESS +#define EINPROGRESS WSAEINPROGRESS +#undef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#undef ENOTCONN +#define ENOTCONN WSAENOTCONN +#undef ECONNRESET +#define ECONNRESET WSAECONNRESET +#undef ETIMEDOUT +#define ETIMEDOUT WAIT_TIMEOUT +#endif +#define ioctl ioctlsocket +#define socklen_t int +#else +#define INVALID_SOCKET SOCKET_ERROR +#include +#if !defined(_WRS_KERNEL) +#include +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define ULONG size_t +#endif + +#include "mutex_type.h" /* Needed for mutex_type */ + +/** socket operation completed successfully */ +#define TCPSOCKET_COMPLETE 0 +#if !defined(SOCKET_ERROR) + /** error in socket operation */ + #define SOCKET_ERROR -1 +#endif +/** must be the same as SOCKETBUFFER_INTERRUPTED */ +#define TCPSOCKET_INTERRUPTED -22 +#define SSL_FATAL -3 + +#if !defined(INET6_ADDRSTRLEN) +#define INET6_ADDRSTRLEN 46 /** only needed for gcc/cygwin on windows */ +#endif + + +#if !defined(max) +#define max(A,B) ( (A) > (B) ? (A):(B)) +#endif + +#include "LinkedList.h" + +/* + * Network write buffers for an MQTT packet + */ +typedef struct +{ + int count; /**> number of buffers/buflens/frees */ + char** buffers; /**> array of byte buffers */ + size_t* buflens; /**> array of lengths of buffers */ + int* frees; /**> array of flags indicating whether each buffer needs to be freed */ + uint8_t mask[4]; /**> websocket mask used to mask the buffer data, if any */ +} PacketBuffers; + + +/** + * Structure to hold all socket data for the module + */ +typedef struct +{ + fd_set rset, /**< socket read set (see select doc) */ + rset_saved; /**< saved socket read set */ + int maxfdp1; /**< max descriptor used +1 (again see select doc) */ + List* clientsds; /**< list of client socket descriptors */ + ListElement* cur_clientsds; /**< current client socket descriptor (iterator) */ + List* connect_pending; /**< list of sockets for which a connect is pending */ + List* write_pending; /**< list of sockets for which a write is pending */ + fd_set pending_wset; /**< socket pending write set for select */ +} Sockets; + + +void Socket_outInitialize(void); +void Socket_outTerminate(void); +int Socket_getReadySocket(int more_work, struct timeval *tp, mutex_type mutex, int* rc); +int Socket_getch(int socket, char* c); +char *Socket_getdata(int socket, size_t bytes, size_t* actual_len, int* rc); +int Socket_putdatas(int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +void Socket_close(int socket); +#if defined(__GNUC__) && defined(__linux__) +/* able to use GNU's getaddrinfo_a to make timeouts possible */ +int Socket_new(const char* addr, size_t addr_len, int port, int* socket, long timeout); +#else +int Socket_new(const char* addr, size_t addr_len, int port, int* socket); +#endif + +int Socket_noPendingWrites(int socket); +char* Socket_getpeer(int sock); + +void Socket_addPendingWrite(int socket); +void Socket_clearPendingWrite(int socket); + +typedef void Socket_writeComplete(int socket, int rc); +void Socket_setWriteCompleteCallback(Socket_writeComplete*); + +#endif /* SOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/SocketBuffer.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/SocketBuffer.h new file mode 100644 index 0000000..0fc7d6e --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/SocketBuffer.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + *******************************************************************************/ + +#if !defined(SOCKETBUFFER_H) +#define SOCKETBUFFER_H + +#if defined(_WIN32) || defined(_WIN64) +#include +#else +#include +#endif + +#if defined(OPENSSL) +#include +#endif + +#if defined(_WIN32) || defined(_WIN64) + typedef WSABUF iobuf; +#else + typedef struct iovec iobuf; +#endif + +typedef struct +{ + int socket; + unsigned int index; + size_t headerlen; + char fixed_header[5]; /**< header plus up to 4 length bytes */ + size_t buflen, /**< total length of the buffer */ + datalen; /**< current length of data in buf */ + char* buf; +} socket_queue; + +typedef struct +{ + int socket, count; + size_t total; +#if defined(OPENSSL) + SSL* ssl; +#endif + size_t bytes; + iobuf iovecs[5]; + int frees[5]; +} pending_writes; + +#define SOCKETBUFFER_COMPLETE 0 +#if !defined(SOCKET_ERROR) + #define SOCKET_ERROR -1 +#endif +#define SOCKETBUFFER_INTERRUPTED -22 /* must be the same value as TCPSOCKET_INTERRUPTED */ + +int SocketBuffer_initialize(void); +void SocketBuffer_terminate(void); +void SocketBuffer_cleanup(int socket); +char* SocketBuffer_getQueuedData(int socket, size_t bytes, size_t* actual_len); +int SocketBuffer_getQueuedChar(int socket, char* c); +void SocketBuffer_interrupted(int socket, size_t actual_len); +char* SocketBuffer_complete(int socket); +void SocketBuffer_queueChar(int socket, char c); + +#if defined(OPENSSL) +int SocketBuffer_pendingWrite(int socket, SSL* ssl, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#else +int SocketBuffer_pendingWrite(int socket, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#endif +pending_writes* SocketBuffer_getWrite(int socket); +int SocketBuffer_writeComplete(int socket); +pending_writes* SocketBuffer_updateWrite(int socket, char* topic, char* payload); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/StackTrace.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/StackTrace.h new file mode 100644 index 0000000..c4f0d43 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/StackTrace.h @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#ifndef STACKTRACE_H_ +#define STACKTRACE_H_ + +#if defined(HIGH_PERFORMANCE) +#define NOSTACKTRACE 1 +#endif + +#include +#include "Log.h" +#include "Thread.h" + +#if defined(NOSTACKTRACE) +#define FUNC_ENTRY +#define FUNC_ENTRY_NOLOG +#define FUNC_ENTRY_MED +#define FUNC_ENTRY_MAX +#define FUNC_EXIT +#define FUNC_EXIT_NOLOG +#define FUNC_EXIT_MED +#define FUNC_EXIT_MAX +#define FUNC_EXIT_RC(x) +#define FUNC_EXIT_MED_RC(x) +#define FUNC_EXIT_MAX_RC(x) +#else +#if defined(_WIN32) || defined(_WIN64) +#define inline __inline +#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM) +#else +#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM) +#endif +#endif + +void StackTrace_entry(const char* name, int line, enum LOG_LEVELS trace); +void StackTrace_exit(const char* name, int line, void* return_value, enum LOG_LEVELS trace); + +void StackTrace_printStack(FILE* dest); +char* StackTrace_get(thread_id_type, char* buf, int bufsize); + +#endif /* STACKTRACE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Thread.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Thread.h new file mode 100644 index 0000000..29903f5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Thread.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + * Ian Craggs, Allan Stockdill-Mander - async client updates + * Ian Craggs - fix for bug #420851 + * Ian Craggs - change MacOS semaphore implementation + *******************************************************************************/ + +#if !defined(THREAD_H) +#define THREAD_H + +#include "MQTTExportDeclarations.h" + +#include "MQTTClient.h" + +#include "mutex_type.h" /* Needed for mutex_type */ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define thread_type HANDLE + #define thread_id_type DWORD + #define thread_return_type DWORD + #define thread_fn LPTHREAD_START_ROUTINE + #define cond_type HANDLE + #define sem_type HANDLE + #undef ETIMEDOUT + #define ETIMEDOUT WSAETIMEDOUT +#else + #include + + #define thread_type pthread_t + #define thread_id_type pthread_t + #define thread_return_type void* + typedef thread_return_type (*thread_fn)(void*); + typedef struct { pthread_cond_t cond; pthread_mutex_t mutex; } cond_type_struct; + typedef cond_type_struct *cond_type; + #if defined(OSX) + #include + typedef dispatch_semaphore_t sem_type; + #else + #include + typedef sem_t *sem_type; + #endif + + cond_type Thread_create_cond(int*); + int Thread_signal_cond(cond_type); + int Thread_wait_cond(cond_type condvar, int timeout); + int Thread_destroy_cond(cond_type); +#endif + +LIBMQTT_API thread_type Thread_start(thread_fn, void*); + +LIBMQTT_API mutex_type Thread_create_mutex(int*); +LIBMQTT_API int Thread_lock_mutex(mutex_type); +LIBMQTT_API int Thread_unlock_mutex(mutex_type); +int Thread_destroy_mutex(mutex_type); + +LIBMQTT_API thread_id_type Thread_getid(); + +sem_type Thread_create_sem(int*); +int Thread_wait_sem(sem_type sem, int timeout); +int Thread_check_sem(sem_type sem); +int Thread_post_sem(sem_type sem); +int Thread_destroy_sem(sem_type sem); + + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Tree.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Tree.h new file mode 100644 index 0000000..dfd70ab --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/Tree.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + + +#if !defined(TREE_H) +#define TREE_H + +#include /* for size_t definition */ + +/*BE +defm defTree(T) // macro to define a tree + +def T concat Node +{ + n32 ptr T concat Node "parent" + n32 ptr T concat Node "left" + n32 ptr T concat Node "right" + n32 ptr T id2str(T) + n32 suppress "size" +} + + +def T concat Tree +{ + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + n32 dec "count" + n32 dec suppress "size" +} + +endm + +defTree(INT) +defTree(STRING) +defTree(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct NodeStruct +{ + struct NodeStruct *parent, /**< pointer to parent tree node, in case we need it */ + *child[2]; /**< pointers to child tree nodes 0 = left, 1 = right */ + void* content; /**< pointer to element content */ + size_t size; /**< size of content */ + unsigned int red : 1; +} Node; + + +/** + * Structure to hold all data for one tree + */ +typedef struct +{ + struct + { + Node *root; /**< root node pointer */ + int (*compare)(void*, void*, int); /**< comparison function */ + } index[2]; + int indexes, /**< no of indexes into tree */ + count; /**< no of items */ + size_t size; /**< heap storage used */ + unsigned int heap_tracking : 1; /**< switch on heap tracking for this tree? */ + unsigned int allow_duplicates : 1; /**< switch to allow duplicate entries */ +} Tree; + + +Tree* TreeInitialize(int(*compare)(void*, void*, int)); +void TreeInitializeNoMalloc(Tree* aTree, int(*compare)(void*, void*, int)); +void TreeAddIndex(Tree* aTree, int(*compare)(void*, void*, int)); + +void* TreeAdd(Tree* aTree, void* content, size_t size); + +void* TreeRemove(Tree* aTree, void* content); + +void* TreeRemoveKey(Tree* aTree, void* key); +void* TreeRemoveKeyIndex(Tree* aTree, void* key, int index); + +void* TreeRemoveNodeIndex(Tree* aTree, Node* aNode, int index); + +void TreeFree(Tree* aTree); + +Node* TreeFind(Tree* aTree, void* key); +Node* TreeFindIndex(Tree* aTree, void* key, int index); + +Node* TreeNextElement(Tree* aTree, Node* curnode); + +int TreeIntCompare(void* a, void* b, int); +int TreePtrCompare(void* a, void* b, int); +int TreeStringCompare(void* a, void* b, int); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/VersionInfo.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/VersionInfo.h new file mode 100644 index 0000000..b3b3e78 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/VersionInfo.h @@ -0,0 +1,7 @@ +#ifndef VERSIONINFO_H +#define VERSIONINFO_H + +#define BUILD_TIMESTAMP "2021-02-11 12:10" +#define CLIENT_VERSION "1.3.8" + +#endif /* VERSIONINFO_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/WebSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/WebSocket.h new file mode 100644 index 0000000..e9f5765 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/WebSocket.h @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2018, 2020 Wind River Systems, Inc. and others. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(WEBSOCKET_H) +#define WEBSOCKET_H + +#include "MQTTPacket.h" + +/** + * WebSocket op codes + * @{ + */ +#define WebSocket_OP_CONTINUE 0x0 /* 0000 - continue frame */ +#define WebSocket_OP_TEXT 0x1 /* 0001 - text frame */ +#define WebSocket_OP_BINARY 0x2 /* 0010 - binary frame */ +#define WebSocket_OP_CLOSE 0x8 /* 1000 - close frame */ +#define WebSocket_OP_PING 0x9 /* 1001 - ping frame */ +#define WebSocket_OP_PONG 0xA /* 1010 - pong frame */ +/** @} */ + +/** + * Various close status codes + * @{ + */ +#define WebSocket_CLOSE_NORMAL 1000 +#define WebSocket_CLOSE_GOING_AWAY 1001 +#define WebSocket_CLOSE_PROTOCOL_ERROR 1002 +#define WebSocket_CLOSE_UNKNOWN_DATA 1003 +#define WebSocket_CLOSE_RESERVED 1004 +#define WebSocket_CLOSE_NO_STATUS_CODE 1005 /* reserved: not to be used */ +#define WebSocket_CLOSE_ABNORMAL 1006 /* reserved: not to be used */ +#define WebSocket_CLOSE_BAD_DATA 1007 +#define WebSocket_CLOSE_POLICY 1008 +#define WebSocket_CLOSE_MSG_TOO_BIG 1009 +#define WebSocket_CLOSE_NO_EXTENSION 1010 +#define WebScoket_CLOSE_UNEXPECTED 1011 +#define WebSocket_CLOSE_TLS_FAIL 1015 /* reserved: not be used */ +/** @} */ + +/* closes a websocket connection */ +void WebSocket_close(networkHandles *net, int status_code, const char *reason); + +/* sends upgrade request */ +int WebSocket_connect(networkHandles *net, const char *uri); + +/* obtain data from network socket */ +int WebSocket_getch(networkHandles *net, char* c); +char *WebSocket_getdata(networkHandles *net, size_t bytes, size_t* actual_len); +size_t WebSocket_framePos(); +void WebSocket_framePosSeekTo(size_t); + +/* send data out, in websocket format only if required */ +int WebSocket_putdatas(networkHandles* net, char** buf0, size_t* buf0len, PacketBuffers* bufs); + +/* releases any resources used by the websocket system */ +void WebSocket_terminate(void); + +/* handles websocket upgrade request */ +int WebSocket_upgrade(networkHandles *net); + +/* Notify the IP address and port of the endpoint to proxy, and wait connection to endpoint */ +int WebSocket_proxy_connect( networkHandles *net, int ssl, const char *hostname); + +#endif /* WEBSOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/mutex_type.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/mutex_type.h new file mode 100644 index 0000000..1e4b9e5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/mutex_type.h @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + *******************************************************************************/ +#if !defined(_MUTEX_TYPE_H_) +#define _MUTEX_TYPE_H_ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define mutex_type HANDLE +#else + #include + #define mutex_type pthread_mutex_t* +#endif + +#endif /* _MUTEX_TYPE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/utf-8.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/utf-8.h new file mode 100644 index 0000000..a7a4270 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/include/utf-8.h @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(UTF8_H) +#define UTF8_H + +int UTF8_validate(int len, const char *data); +int UTF8_validateString(const char* string); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libOpenSSL_s.a new file mode 100644 index 0000000..f8c0b9f Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libPahoMQTT_s.a new file mode 100644 index 0000000..aa7035c Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libar_posix_s.a new file mode 100644 index 0000000..3a88997 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libarsystem.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libarsystem.a new file mode 100644 index 0000000..97f3bf6 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/libarsystem.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/librtk_lib.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/librtk_lib.a new file mode 100644 index 0000000..d498981 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V3.10.0/SG4/librtk_lib.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/Binary.lby b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/Binary.lby new file mode 100644 index 0000000..cae32e9 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/Binary.lby @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Base64.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Base64.h new file mode 100644 index 0000000..7022ce8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Base64.h @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2018 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(BASE64_H) +#define BASE64_H + +/** type for size of a buffer, it saves passing around @p size_t (unsigned long long or unsigned long int) */ +typedef unsigned int b64_size_t; +/** type for raw base64 data */ +typedef unsigned char b64_data_t; + +/** + * Decodes base64 data + * + * @param[out] out decoded data + * @param[in] out_len length of output buffer + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the amount of data decoded + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_decode( b64_data_t *out, b64_size_t out_len, + const char *in, b64_size_t in_len ); + +/** + * Size of buffer required to decode base64 data + * + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the decoded string would require + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_decodeLength( const char *in, b64_size_t in_len ); + +/** + * Encodes base64 data + * + * @param[out] out encode base64 string + * @param[in] out_len length of output buffer + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the amount of data encoded + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_encode( char *out, b64_size_t out_len, + const b64_data_t *in, b64_size_t in_len ); + +/** + * Size of buffer required to encode base64 data + * + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the encoded string would require + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_encodeLength( const b64_data_t *in, b64_size_t in_len ); + +#endif /* BASE64_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Clients.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Clients.h new file mode 100644 index 0000000..a3ddb1f --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Clients.h @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - add SSL support + * Ian Craggs - fix for bug 413429 - connectionLost not called + * Ian Craggs - change will payload to binary + * Ian Craggs - password to binary + * Ian Craggs - MQTT 5 support + *******************************************************************************/ + +#if !defined(CLIENTS_H) +#define CLIENTS_H + +#include +#include "MQTTTime.h" +#if defined(OPENSSL) +#if defined(_WIN32) || defined(_WIN64) +#include +#endif +#include +#endif +#include "MQTTClient.h" +#include "LinkedList.h" +#include "MQTTClientPersistence.h" + +/** + * Stored publication data to minimize copying + */ +typedef struct +{ + char *topic; + int topiclen; + char* payload; + int payloadlen; + int refcount; + uint8_t mask[4]; +} Publications; + +/** + * Client publication message data + */ +typedef struct +{ + int qos; + int retain; + int msgid; + int MQTTVersion; + MQTTProperties properties; + Publications *publish; + START_TIME_TYPE lastTouch; /**> used for retry and expiry */ + char nextMessageType; /**> PUBREC, PUBREL, PUBCOMP */ + int len; /**> length of the whole structure+data */ +} Messages; + +/** + * Client will message data + */ +typedef struct +{ + char *topic; + int payloadlen; + void *payload; + int retained; + int qos; +} willMessages; + +typedef struct +{ + int socket; + START_TIME_TYPE lastSent; + START_TIME_TYPE lastReceived; + START_TIME_TYPE lastPing; +#if defined(OPENSSL) + SSL* ssl; + SSL_CTX* ctx; + char *https_proxy; + char *https_proxy_auth; +#endif + char *http_proxy; + char *http_proxy_auth; + int websocket; /**< socket has been upgraded to use web sockets */ + char *websocket_key; + const MQTTClient_nameValue* httpHeaders; +} networkHandles; + + +/* connection states */ +/** no connection in progress, see connected value */ +#define NOT_IN_PROGRESS 0x0 +/** TCP connection in progress */ +#define TCP_IN_PROGRESS 0x1 +/** SSL connection in progress */ +#define SSL_IN_PROGRESS 0x2 +/** Websocket connection in progress */ +#define WEBSOCKET_IN_PROGRESS 0x3 +/** TCP completed, waiting for MQTT ACK */ +#define WAIT_FOR_CONNACK 0x4 +/** Proxy connection in progress */ +#define PROXY_CONNECT_IN_PROGRESS 0x5 +/** Disconnecting */ +#define DISCONNECTING -2 + +/** + * Data related to one client + */ +typedef struct +{ + char* clientID; /**< the string id of the client */ + const char* username; /**< MQTT v3.1 user name */ + int passwordlen; /**< MQTT password length */ + const void* password; /**< MQTT v3.1 binary password */ + unsigned int cleansession : 1; /**< MQTT V3 clean session flag */ + unsigned int cleanstart : 1; /**< MQTT V5 clean start flag */ + unsigned int connected : 1; /**< whether it is currently connected */ + unsigned int good : 1; /**< if we have an error on the socket we turn this off */ + unsigned int ping_outstanding : 1; + signed int connect_state : 4; + networkHandles net; /**< network info for this client */ + int msgID; /**< the MQTT message id */ + int keepAliveInterval; /**< the MQTT keep alive interval */ + int retryInterval; + int maxInflightMessages; /**< the max number of inflight outbound messages we allow */ + willMessages* will; /**< the MQTT will message, if any */ + List* inboundMsgs; /**< inbound in flight messages */ + List* outboundMsgs; /**< outbound in flight messages */ + List* messageQueue; /**< inbound complete but undelivered messages */ + unsigned int qentry_seqno; + void* phandle; /**< the persistence handle */ + MQTTClient_persistence* persistence; /**< a persistence implementation */ + MQTTPersistence_beforeWrite* beforeWrite; /**< persistence write callback */ + MQTTPersistence_afterRead* afterRead; /**< persistence read callback */ + void* beforeWrite_context; /**< context to be used with the persistence beforeWrite callbacks */ + void* afterRead_context; /**< context to be used with the persistence afterRead callback */ + void* context; /**< calling context - used when calling disconnect_internal */ + int MQTTVersion; /**< the version of MQTT being used, 3, 4 or 5 */ + int sessionExpiry; /**< MQTT 5 session expiry */ + char* httpProxy; /**< HTTP proxy for websockets */ + char* httpsProxy; /**< HTTPS proxy for websockets */ +#if defined(OPENSSL) + MQTTClient_SSLOptions *sslopts; /**< the SSL/TLS connect options */ + SSL_SESSION* session; /**< SSL session pointer for fast handhake */ +#endif +} Clients; + +int clientIDCompare(void* a, void* b); +int clientSocketCompare(void* a, void* b); + +/** + * Configuration data related to all clients + */ +typedef struct +{ + const char* version; + List* clients; +} ClientStates; + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Heap.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Heap.h new file mode 100644 index 0000000..f89a760 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Heap.h @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - use tree data structure instead of list + *******************************************************************************/ + + +#if !defined(HEAP_H) +#define HEAP_H + +#if defined(HIGH_PERFORMANCE) +#define NO_HEAP_TRACKING 1 +#endif + +#define PAHO_MEMORY_ERROR -99 + +#include "MQTTExportDeclarations.h" + +#include +#include + +#if !defined(NO_HEAP_TRACKING) + +#if !defined(TREE_C) +/** + * redefines malloc to use "mymalloc" so that heap allocation can be tracked + * @param x the size of the item to be allocated + * @return the pointer to the item allocated, or NULL + */ +#define malloc(x) mymalloc(__FILE__, __LINE__, x) + +/** + * redefines realloc to use "myrealloc" so that heap allocation can be tracked + * @param a the heap item to be reallocated + * @param b the new size of the item + * @return the new pointer to the heap item + */ +#define realloc(a, b) myrealloc(__FILE__, __LINE__, a, b) + +/** + * redefines free to use "myfree" so that heap allocation can be tracked + * @param x the size of the item to be freed + */ +#define free(x) myfree(__FILE__, __LINE__, x) + +#endif + +/** + * Information about the state of the heap. + */ +typedef struct +{ + size_t current_size; /**< current size of the heap in bytes */ + size_t max_size; /**< max size the heap has reached in bytes */ +} heap_info; + +#if defined(__cplusplus) + extern "C" { +#endif + +void* mymalloc(char*, int, size_t size); +void* myrealloc(char*, int, void* p, size_t size); +void myfree(char*, int, void* p); + +void Heap_scan(FILE* file); +int Heap_initialize(void); +void Heap_terminate(void); +LIBMQTT_API heap_info* Heap_get_info(void); +int HeapDump(FILE* file); +int HeapDumpString(FILE* file, char* str); +void* Heap_findItem(void* p); +void Heap_unlink(char* file, int line, void* p); +#ifdef __cplusplus + } +#endif + +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/LinkedList.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/LinkedList.h new file mode 100644 index 0000000..e390012 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/LinkedList.h @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + * Ian Craggs - change size types from int to size_t + *******************************************************************************/ + +#if !defined(LINKEDLIST_H) +#define LINKEDLIST_H + +#include /* for size_t definition */ + +/*BE +defm defList(T) + +def T concat Item +{ + at 4 + n32 ptr T concat Item suppress "next" + at 0 + n32 ptr T concat Item suppress "prev" + at 8 + n32 ptr T id2str(T) +} + +def T concat List +{ + n32 ptr T concat Item suppress "first" + n32 ptr T concat Item suppress "last" + n32 ptr T concat Item suppress "current" + n32 dec "count" + n32 suppress "size" +} +endm + +defList(INT) +defList(STRING) +defList(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct ListElementStruct +{ + struct ListElementStruct *prev, /**< pointer to previous list element */ + *next; /**< pointer to next list element */ + void* content; /**< pointer to element content */ +} ListElement; + + +/** + * Structure to hold all data for one list + */ +typedef struct +{ + ListElement *first, /**< first element in the list */ + *last, /**< last element in the list */ + *current; /**< current element in the list, for iteration */ + int count; /**< no of items */ + size_t size; /**< heap storage used */ +} List; + +void ListZero(List*); +List* ListInitialize(void); + +ListElement* ListAppend(List* aList, void* content, size_t size); +void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, size_t size); +ListElement* ListInsert(List* aList, void* content, size_t size, ListElement* index); + +int ListRemove(List* aList, void* content); +int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*)); +void* ListDetachHead(List* aList); +int ListRemoveHead(List* aList); +void* ListPopTail(List* aList); + +int ListDetach(List* aList, void* content); +int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*)); + +void ListFree(List* aList); +void ListEmpty(List* aList); +void ListFreeNoContent(List* aList); + +ListElement* ListNextElement(List* aList, ListElement** pos); +ListElement* ListPrevElement(List* aList, ListElement** pos); + +ListElement* ListFind(List* aList, void* content); +ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*)); + +int intcompare(void* a, void* b); +int stringcompare(void* a, void* b); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Log.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Log.h new file mode 100644 index 0000000..102e31d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Log.h @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + *******************************************************************************/ + +#if !defined(LOG_H) +#define LOG_H + +/*BE +map LOG_LEVELS +{ + "TRACE_MAXIMUM" 1 + "TRACE_MEDIUM" 2 + "TRACE_MINIMUM" 3 + "TRACE_PROTOCOL" 4 + + "ERROR" 5 + "SEVERE" 6 + "FATAL" 7 +} +BE*/ + +enum LOG_LEVELS { + INVALID_LEVEL = -1, + TRACE_MAXIMUM = 1, + TRACE_MEDIUM, + TRACE_MINIMUM, + TRACE_PROTOCOL, + LOG_ERROR, + LOG_SEVERE, + LOG_FATAL, +}; + + +/*BE +def trace_settings_type +{ + n32 map LOG_LEVELS "trace_level" + n32 dec "max_trace_entries" + n32 dec "trace_output_level" +} +BE*/ +typedef struct +{ + enum LOG_LEVELS trace_level; /**< trace level */ + int max_trace_entries; /**< max no of entries in the trace buffer */ + enum LOG_LEVELS trace_output_level; /**< trace level to output to destination */ +} trace_settings_type; + +extern trace_settings_type trace_settings; + +#define LOG_PROTOCOL TRACE_PROTOCOL +#define TRACE_MAX TRACE_MAXIMUM +#define TRACE_MIN TRACE_MINIMUM +#define TRACE_MED TRACE_MEDIUM + +typedef struct +{ + const char* name; + const char* value; +} Log_nameValue; + +int Log_initialize(Log_nameValue*); +void Log_terminate(void); + +void Log(enum LOG_LEVELS, int, const char *, ...); +void Log_stackTrace(enum LOG_LEVELS, int, int, int, const char*, int, int*); + +typedef void Log_traceCallback(enum LOG_LEVELS level, const char *message); +void Log_setTraceCallback(Log_traceCallback* callback); +void Log_setTraceLevel(enum LOG_LEVELS level); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTAsync.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTAsync.h new file mode 100644 index 0000000..f728ba5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTAsync.h @@ -0,0 +1,2345 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation + * Ian Craggs, Allan Stockdill-Mander - SSL connections + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - fix for bug 444103 - success/failure callbacks not invoked + * Ian Craggs - automatic reconnect and offline buffering (send while disconnected) + * Ian Craggs - binary will message + * Ian Craggs - binary password + * Ian Craggs - remove const on eyecatchers #168 + * Ian Craggs - MQTT 5.0 + *******************************************************************************/ + +/********************************************************************/ + +/** + * @cond MQTTAsync_main + * @mainpage Asynchronous MQTT client library for C + * + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An Asynchronous MQTT client library for C. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the Asynchronous MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions
  • + *
  • Connect the client to an MQTT server
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref publish
  • + *
  • @ref subscribe
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
  • @ref auto_reconnect
  • + *
  • @ref offline_publish
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTASYNC_H) +#define MQTTASYNC_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTASYNC_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTASYNC_FAILURE -1 + +/* error code -2 is MQTTAsync_PERSISTENCE_ERROR */ + +#define MQTTASYNC_PERSISTENCE_ERROR -2 + +/** + * Return code: The client is disconnected. + */ +#define MQTTASYNC_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTASYNC_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTASYNC_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTASYNC_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTASYNC_BAD_STRUCTURE -8 +/** + * Return code: A qos parameter is not 0, 1 or 2 + */ +#define MQTTASYNC_BAD_QOS -9 +/** + * Return code: All 65535 MQTT msgids are being used + */ +#define MQTTASYNC_NO_MORE_MSGIDS -10 +/** + * Return code: the request is being discarded when not complete + */ +#define MQTTASYNC_OPERATION_INCOMPLETE -11 +/** + * Return code: no more messages can be buffered + */ +#define MQTTASYNC_MAX_BUFFERED_MESSAGES -12 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTASYNC_SSL_NOT_SUPPORTED -13 + /** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if the TLS version of the library + * is linked with. + */ +#define MQTTASYNC_BAD_PROTOCOL -14 + /** + * Return code: don't use options for another version of MQTT + */ + #define MQTTASYNC_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the client's version of MQTT + */ + #define MQTTASYNC_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic + */ + #define MQTTASYNC_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 +/** + * MQTT version to connect with: 5 + */ +#define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTAsync_init_options; + +#define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt (0) + */ +LIBMQTT_API void MQTTAsync_global_init(MQTTAsync_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTAsync_create(). + */ +typedef void* MQTTAsync; +/** + * A value representing an MQTT message. A token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTAsync_publish(), + * MQTTAsync_publishMessage(), + * MQTTAsync_deliveryComplete(), and + * MQTTAsync_getPendingTokens()). + */ +typedef int MQTTAsync_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTAsync_publishMessage(), + * MQTTAsync_publish(), MQTTAsync_receive(), MQTTAsync_freeMessage() + * and MQTTAsync_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. This is an output parameter only. + */ + int dup; + /** The message identifier is reserved for internal use by the + * MQTT client and server. It is an output parameter only - writing + * to it will serve no purpose. It contains the MQTT message id of + * an incoming publish message. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTAsync_message; + +#define MQTTAsync_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTAsync_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTAsync_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTAsync_freeMessage must be called. + * To free the topic name storage, ::MQTTAsync_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTAsync_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTAsync_messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages to the server. The function is + * registered with the client library by passing it as an argument to MQTTAsync_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTAsync_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param token The ::MQTTAsync_token associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the tokens returned from calls to + * MQTTAsync_send() and MQTTAsync_sendMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTAsync_deliveryComplete(void* context, MQTTAsync_token token); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTAsync_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connectionLost(void* context, char* cause); + + +/** + * This is a callback function, which will be called when the client + * library successfully connects. This is superfluous when the connection + * is made in response to a MQTTAsync_connect call, because the onSuccess + * callback can be used. It is intended for use when automatic reconnect + * is enabled, so that when a reconnection attempt succeeds in the background, + * the application is notified and can take any required actions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connected(void* context, char* cause); + +/** + * This is a callback function, which will be called when the client + * library receives a disconnect packet. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param properties the properties in the disconnect packet. + * @param properties the reason code from the disconnect packet + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTAsync_disconnected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDisconnected(MQTTAsync handle, void* context, MQTTAsync_disconnected* co); + +/** The connect options that can be updated before an automatic reconnect. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQCD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name parameter. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + const char* username; + /** + * The password parameter of the MQTT authentication. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; +} MQTTAsync_connectData; + +#define MQTTAsync_connectData_initializer {{'M', 'Q', 'C', 'D'}, 0, NULL, {0, NULL}} + +/** + * This is a callback function which will allow the client application to update the + * connection data. + * @param data The connection data which can be modified by the application. + * @return Return a non-zero value to update the connect data, zero to keep the same data. + */ +typedef int MQTTAsync_updateConnectOptions(void* context, MQTTAsync_connectData* data); + +/** + * Sets the MQTTAsync_updateConnectOptions() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_updateConnectOptions() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setUpdateConnectOptions(MQTTAsync handle, void* context, MQTTAsync_updateConnectOptions* co); + +/** + * Sets the MQTTPersistence_beforeWrite() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setBeforePersistenceWrite(MQTTAsync handle, void* context, MQTTPersistence_beforeWrite* co); + + +/** + * Sets the MQTTPersistence_afterRead() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setAfterPersistenceRead(MQTTAsync handle, void* context, MQTTPersistence_afterRead* co); + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** A numeric code identifying the error. */ + int code; + /** Optional text explaining the error. Can be NULL. */ + const char *message; +} MQTTAsync_failureData; + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQFD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** The MQTT reason code returned. */ + enum MQTTReasonCodes reasonCode; + /** The MQTT properties on the ack, if any. */ + MQTTProperties properties; + /** A numeric code identifying the MQTT client library error. */ + int code; + /** Optional further text explaining the error. Can be NULL. */ + const char *message; + /** Packet type on which the failure occurred - used for publish QoS 1/2 exchanges*/ + int packet_type; +} MQTTAsync_failureData5; + +#define MQTTAsync_failureData5_initializer {{'M', 'Q', 'F', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, 0, NULL} + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribe, the granted QoS of the subscription returned by the server. + * Also for subscribeMany, if only 1 subscription was requested. */ + int qos; + /** For subscribeMany, if more than one subscription was requested, + * the list of granted QoSs of the subscriptions returned by the server. */ + int* qosList; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + } alt; +} MQTTAsync_successData; + + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + char struct_id[4]; /**< The eyecatcher for this structure. Will be MQSD. */ + int struct_version; /**< The version number of this structure. Will be 0 */ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + enum MQTTReasonCodes reasonCode; /**< MQTT V5 reason code returned */ + MQTTProperties properties; /**< MQTT V5 properties returned, if any */ + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } sub; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + /** For unsubscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } unsub; + } alt; +} MQTTAsync_successData5; + +#define MQTTAsync_successData5_initializer {{'M', 'Q', 'S', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer} + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onSuccess. + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess5(void* context, MQTTAsync_successData5* response); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure(void* context, MQTTAsync_failureData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onFailure. + * The application must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure5(void* context, MQTTAsync_failureData5* response); + +/** Structure to define call options. For MQTT 5.0 there is input data as well as that + * describing the response method. So there is now also a synonym ::MQTTAsync_callOptions + * to better reflect the use. This responseOptions name is kept for backward + * compatibility. + */ +typedef struct MQTTAsync_responseOptions +{ + /** The eyecatcher for this structure. Must be MQTR */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * if 0, no MQTTV5 options */ + int struct_version; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the API call fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * A token is returned from the call. It can be used to track + * the state of this request, both in the callbacks and in future calls + * such as ::MQTTAsync_waitForCompletion. + */ + MQTTAsync_token token; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /* + * MQTT V5 subscribe options, when used with subscribe only. + */ + MQTTSubscribe_options subscribeOptions; + /* + * MQTT V5 subscribe option count, when used with subscribeMany only. + * The number of entries in the subscribe_options_list array. + */ + int subscribeOptionsCount; + /* + * MQTT V5 subscribe option array, when used with subscribeMany only. + */ + MQTTSubscribe_options* subscribeOptionsList; +} MQTTAsync_responseOptions; + +#define MQTTAsync_responseOptions_initializer { {'M', 'Q', 'T', 'R'}, 1, NULL, NULL, 0, 0, NULL, NULL, MQTTProperties_initializer, MQTTSubscribe_options_initializer, 0, NULL} + +/** A synonym for responseOptions to better reflect its usage since MQTT 5.0 */ +typedef struct MQTTAsync_responseOptions MQTTAsync_callOptions; +#define MQTTAsync_callOptions_initializer MQTTAsync_responseOptions_initializer + +/** + * This function sets the global callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. If this callback is not set, an error will be returned. + * You must set this callback because otherwise there would be + * no way to deliver any incoming messages. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl, + MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc); + +/** + * This function sets the callback function for a connection lost event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed the callback functions to provide + * access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ + +LIBMQTT_API int MQTTAsync_setConnectionLostCallback(MQTTAsync handle, void* context, + MQTTAsync_connectionLost* cl); + +/** + * This function sets the callback function for a message arrived event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. You can set this to NULL if your application doesn't handle + * receipt of messages. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setMessageArrivedCallback(MQTTAsync handle, void* context, + MQTTAsync_messageArrived* ma); + +/** + * This function sets the callback function for a delivery complete event + * for a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDeliveryCompleteCallback(MQTTAsync handle, void* context, + MQTTAsync_deliveryComplete* dc); + +/** + * Sets the MQTTAsync_connected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co); + + +/** + * Reconnects a client with the previously used connect options. Connect + * must have previously been called for this to work. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_reconnect(MQTTAsync handle); + + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTAsync_persistence). See also MQTTAsync_destroy(). + * @param handle A pointer to an ::MQTTAsync handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of + * the library is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTASYNC_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTAsync_create(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTAsync_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2 or 3 + * 0 means no MQTTVersion + * 1 means no allowDisconnectedSendAtAnyTime, deleteOldestMessages, restoreMessages + * 2 means no persistQoS0 + */ + int struct_version; + /** Whether to allow messages to be sent when the client library is not connected. */ + int sendWhileDisconnected; + /** The maximum number of messages allowed to be buffered while not connected. */ + int maxBufferedMessages; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; + /** + * Allow sending of messages while disconnected before a first successful connect. + */ + int allowDisconnectedSendAtAnyTime; + /* + * When the maximum number of buffered messages is reached, delete the oldest rather than the newest. + */ + int deleteOldestMessages; + /* + * Restore messages from persistence on create - or clear it. + */ + int restoreMessages; + /* + * Persist QoS0 publish commands - an option to not persist them. + */ + int persistQoS0; +} MQTTAsync_createOptions; + +#define MQTTAsync_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_DEFAULT, 0, 0, 1, 1} + +#define MQTTAsync_createOptions_initializer5 { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_5, 0, 0, 1, 1} + + +LIBMQTT_API int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTAsync_createOptions* options); + +/** + * MQTTAsync_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTAsync_willOptions + * structure is passed in the MQTTAsync_connectOptions structure used in the + * MQTTAsync_connect() call that connects the client to the server. The pointer + * to MQTTAsync_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 indicates no binary will message support + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTAsync_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTAsync_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTAsync_willOptions; + +#define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTAsync_SSLOptions; + +#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** Utility structure where name/value pairs are needed */ +typedef struct +{ + const char* name; /**< name string */ + const char* value; /**< value string */ +} MQTTAsync_nameValue; + +/** + * MQTTAsync_connectOptions defines several settings that control the way the + * client connects to an MQTT server. Default values are set in + * MQTTAsync_connectOptions_initializer. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3 4 5 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no automatic reconnect options + * 4 signifies no binary password option (just string) + * 5 signifies no MQTTV5 properties + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + * Set to 0 if you do not want any keep alive processing. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTAsync_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This controls how many messages can be in-flight simultaneously. + */ + int maxInflight; + /** + * This is a pointer to an MQTTAsync_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTAsync_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTAsync_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTAsync_SSLOptions* ssl; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * The number of entries in the serverURIs array. + */ + int serverURIcount; + /** + * An array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a domain name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + */ + int MQTTVersion; + /** + * Reconnect automatically in the case of a connection being lost? + */ + int automaticReconnect; + /** + * Minimum retry interval in seconds. Doubled on each failed retry. + */ + int minRetryInterval; + /** + * Maximum retry interval in seconds. The doubling stops here on failed retries. + */ + int maxRetryInterval; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * MQTT V5 properties for connect + */ + MQTTProperties *connectProperties; + /** + * MQTT V5 properties for the will message in the connect + */ + MQTTProperties *willProperties; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * HTTP headers for websockets + */ + const MQTTAsync_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTAsync_connectOptions; + + +#define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + + +/** + * This function attempts to connect a previously-created client (see + * MQTTAsync_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTAsync_setCallbacks() prior to MQTTAsync_connect(). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options A pointer to a valid MQTTAsync_connectOptions + * structure. + * @return ::MQTTASYNC_SUCCESS if the client connect request was accepted. + * If the client was unable to connect to the server, an error code is + * returned via the onFailure callback, if set. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options); + +/** Options for the ::MQTTAsync_disconnect call */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTD. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. 0 signifies no V5 properties */ + int struct_version; + /** + * The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + */ + int timeout; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /** + * Reason code for MQTTV5 disconnect + */ + enum MQTTReasonCodes reasonCode; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; +} MQTTAsync_disconnectOptions; + +#define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 0, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +#define MQTTAsync_disconnectOptions_initializer5 { {'M', 'Q', 'T', 'D'}, 1, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTAsync_connectOptions.cleansession and MQTTAsync_connect()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions* options); + + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTAsync_isConnected(MQTTAsync handle); + + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTAsync_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTAsync_subscribe(MQTTAsync handle, const char* topic, int qos, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTAsync_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char* const* topic, const int* qos, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTAsync_unsubscribe(MQTTAsync handle, const char* topic, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const* topic, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to publish a message to a given topic (see also + * ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * This is optional and can be set to NULL. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_send(MQTTAsync handle, const char* destinationName, int payloadlen, const void* payload, int qos, + int retained, MQTTAsync_responseOptions* response); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTAsync_publish()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param msg A pointer to a valid MQTTAsync_message structure containing + * the payload and attributes of the message to be published. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_sendMessage(MQTTAsync handle, const char* destinationName, const MQTTAsync_message* msg, MQTTAsync_responseOptions* response); + + +/** + * This function sets a pointer to an array of tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param tokens The address of a pointer to an ::MQTTAsync_token. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTASYNC_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens); + +/** + * Tests whether a request corresponding to a token is complete. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @return 1 if the request has been completed, 0 if not. + */ +#define MQTTASYNC_TRUE 1 +LIBMQTT_API int MQTTAsync_isComplete(MQTTAsync handle, MQTTAsync_token token); + + +/** + * Waits for a request corresponding to a token to complete. This only works for + * messages with QoS greater than 0. A QoS 0 message has no MQTT token. + * This function will always return ::MQTTASYNC_SUCCESS for a QoS 0 message. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @param timeout the maximum time to wait for completion, in milliseconds + * @return ::MQTTASYNC_SUCCESS if the request has been completed in the time allocated, + * ::MQTTASYNC_FAILURE or ::MQTTASYNC_DISCONNECTED if not. + */ +LIBMQTT_API int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token token, unsigned long timeout); + + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTAsync_free() library function. + * @param msg The address of a pointer to the ::MQTTAsync_message structure + * to be freed. + */ +LIBMQTT_API void MQTTAsync_freeMessage(MQTTAsync_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTAsync_free(void* ptr); + +/** + * This function is used to allocate memory to be used or freed by the MQTT C client library, + * especially the data in the ::MQTTPersistence_afterRead and ::MQTTPersistence_beforeWrite + * callbacks. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. + * @param size The size of the memory to be allocated. + */ +LIBMQTT_API void* MQTTAsync_malloc(size_t size); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTAsync_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTAsync + * structure to be freed. + */ +LIBMQTT_API void MQTTAsync_destroy(MQTTAsync* handle); + + + +enum MQTTASYNC_TRACE_LEVELS +{ + MQTTASYNC_TRACE_MAXIMUM = 1, + MQTTASYNC_TRACE_MEDIUM, + MQTTASYNC_TRACE_MINIMUM, + MQTTASYNC_TRACE_PROTOCOL, + MQTTASYNC_TRACE_ERROR, + MQTTASYNC_TRACE_SEVERE, + MQTTASYNC_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTAsync_setTraceLevel(enum MQTTASYNC_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTAsync_traceCallback(enum MQTTASYNC_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTAsync_setTraceCallback(MQTTAsync_traceCallback* callback); + +/** + * This function returns version information about the library. + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void); + +/** + * Returns a pointer to a string representation of the error code, or NULL. + * Do not free after use. Returns NULL if the error code is unknown. + * @param code the MQTTASYNC_ return code. + * @return a static string representation of the error code. + */ +LIBMQTT_API const char* MQTTAsync_strerror(int code); + + +/*! + * @cond MQTTAsync_main + * @page async Threading + * The client application runs on several threads. + * Processing of handshaking and maintaining + * the network connection is performed in the background. + * This API is thread safe: functions may be called by multiple application + * threads. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(), + * MQTTAsync_connectionLost() and MQTTAsync_deliveryComplete()). + * In addition, some functions allow success and failure callbacks to be set + * for individual requests, in the ::MQTTAsync_responseOptions structure. Applications + * can be written as a chain of callback functions. + * + * @page callbacks Callbacks + * Any function from this API may be used within a callback. It is not advisable to + * use ::MQTTAsync_waitForCompletion within a callback, however, as it is the only + * API call that may take some time to complete, which may cause unpredictable + * behaviour. All the other API calls are intended to complete quickly, starting + * a request in the background, with success or failure notified by other callbacks. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * A log message will be written to highlight the issue, but it is up + * to the application to protect against this situation. + * + * @page auto_reconnect Automatic Reconnect + * The ability for the client library to reconnect automatically in the event + * of a connection failure was added in 1.1. The connection lost callback + * allows a flexible response to the loss of a connection, so almost any + * behaviour can be implemented in that way. Automatic reconnect does have the + * advantage of being a little simpler to use. + * + * To switch on automatic reconnect, the connect options field + * automaticReconnect should be set to non-zero. The minimum and maximum times + * before the next connection attempt can also be set, the defaults being 1 and + * 60 seconds. At each failure to reconnect, the retry interval is doubled until + * the maximum value is reached, and there it stays until the connection is + * successfully re-established whereupon it is reset. + * + * When a reconnection attempt is successful, the ::MQTTAsync_connected callback + * function is invoked, if set by calling ::MQTTAsync_setConnected. This allows + * the application to take any actions needed, such as amending subscriptions. + * + * @page offline_publish Publish While Disconnected + * This feature was not originally available because with persistence enabled, + * messages could be stored locally without ever knowing if they could be sent. + * The client application could have created the client with an erroneous broker + * address or port for instance. + * + * To enable messages to be published when the application is disconnected + * ::MQTTAsync_createWithOptions must be used instead of ::MQTTAsync_create to + * create the client object. The ::MQTTAsync_createOptions field sendWhileDisconnected + * must be set to non-zero, and the maxBufferedMessages field set as required - + * the default being 100. + * + * ::MQTTAsync_getPendingTokens can be called to return the ids of the messages + * waiting to be sent, or for which the sending process has not completed. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTAsync_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page publish Publication example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed\n"); + finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + finished = 1; +} + +void onSendFailure(void* context, MQTTAsync_failureData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message send failed token %d error code %d\n", response->token, response->code); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +void onSend(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message with token value %d delivery confirmed\n", response->token); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response ? response->code : 0); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + MQTTAsync_message pubmsg = MQTTAsync_message_initializer; + int rc; + + printf("Successful connection\n"); + opts.onSuccess = onSend; + opts.onFailure = onSendFailure; + opts.context = client; + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start sendMessage, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +int messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* m) +{ + // not expecting any messages + return 1; +} + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to create client object, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + if ((rc = MQTTAsync_setCallbacks(client, NULL, connlost, messageArrived, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callback, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (!finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + MQTTAsync_destroy(&client); + return rc; +} + + * @endcode + * @page subscribe Subscription example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int disc_finished = 0; +int subscribed = 0; +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + if (cause) + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTAsync_freeMessage(&message); + MQTTAsync_free(topicName); + return 1; +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed, rc %d\n", response->code); + disc_finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + disc_finished = 1; +} + +void onSubscribe(void* context, MQTTAsync_successData* response) +{ + printf("Subscribe succeeded\n"); + subscribed = 1; +} + +void onSubscribeFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Subscribe failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + int rc; + + printf("Successful connection\n"); + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + opts.onSuccess = onSubscribe; + opts.onFailure = onSubscribeFailure; + opts.context = client; + if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start subscribe, return code %d\n", rc); + finished = 1; + } +} + + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer; + int rc; + int ch; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) + != MQTTASYNC_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTAsync_setCallbacks(client, client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + while (!subscribed && !finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + if (finished) + goto exit; + + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + disc_opts.onSuccess = onDisconnect; + disc_opts.onFailure = onDisconnectFailure; + if ((rc = MQTTAsync_disconnect(client, &disc_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + while (!disc_finished) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + +destroy_exit: + MQTTAsync_destroy(&client); +exit: + return rc; +} + + * @endcode +* @page tracing Tracing + * + * Runtime tracing can be controlled by environment variables or API calls. + * + * #### Environment variables + * + * Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable. + * A value of ON, or stdout, prints to stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * #### Trace API calls + * + * MQTTAsync_traceCallback() is used to set a callback function which is called whenever trace + * information is available. This will be the same information as that printed if the + * environment variables were used to control the trace. + * + * The MQTTAsync_setTraceLevel() calls is used to set the maximum level of trace entries that will be + * passed to the callback function. The levels are: + * 1. ::MQTTASYNC_TRACE_MAXIMUM + * 2. ::MQTTASYNC_TRACE_MEDIUM + * 3. ::MQTTASYNC_TRACE_MINIMUM + * 4. ::MQTTASYNC_TRACE_PROTOCOL + * 5. ::MQTTASYNC_TRACE_ERROR + * 6. ::MQTTASYNC_TRACE_SEVERE + * 7. ::MQTTASYNC_TRACE_FATAL + * + * Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned. + * Choosing ::MQTTASYNC_TRACE_ERROR will cause ERROR, SEVERE and FATAL trace entries to be returned + * to the callback function. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ + +#if defined(__cplusplus) + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTAsyncUtils.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTAsyncUtils.h new file mode 100644 index 0000000..42a3145 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTAsyncUtils.h @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + +#if !defined(MQTTASYNCUTILS_H_) +#define MQTTASYNCUTILS_H_ + +#include "MQTTPacket.h" +#include "Thread.h" + +#define URI_TCP "tcp://" +#define URI_WS "ws://" +#define URI_WSS "wss://" + +enum MQTTAsync_threadStates +{ + STOPPED, STARTING, RUNNING, STOPPING +}; + +typedef struct +{ + MQTTAsync_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} qEntry; + +typedef struct +{ + int type; + MQTTAsync_onSuccess* onSuccess; + MQTTAsync_onFailure* onFailure; + MQTTAsync_onSuccess5* onSuccess5; + MQTTAsync_onFailure5* onFailure5; + MQTTAsync_token token; + void* context; + START_TIME_TYPE start_time; + MQTTProperties properties; + union + { + struct + { + int count; + char** topics; + int* qoss; + MQTTSubscribe_options opts; + MQTTSubscribe_options* optlist; + } sub; + struct + { + int count; + char** topics; + } unsub; + struct + { + char* destinationName; + int payloadlen; + void* payload; + int qos; + int retained; + } pub; + struct + { + int internal; + int timeout; + enum MQTTReasonCodes reasonCode; + } dis; + struct + { + int currentURI; + int MQTTVersion; /**< current MQTT version being used to connect */ + } conn; + } details; +} MQTTAsync_command; + +typedef struct MQTTAsync_struct +{ + char* serverURI; + int ssl; + int websocket; + Clients* c; + + /* "Global", to the client, callback definitions */ + MQTTAsync_connectionLost* cl; + MQTTAsync_messageArrived* ma; + MQTTAsync_deliveryComplete* dc; + void* clContext; /* the context to be associated with the conn lost callback*/ + void* maContext; /* the context to be associated with the msg arrived callback*/ + void* dcContext; /* the context to be associated with the deliv complete callback*/ + + MQTTAsync_connected* connected; + void* connected_context; /* the context to be associated with the connected callback*/ + + MQTTAsync_disconnected* disconnected; + void* disconnected_context; /* the context to be associated with the disconnected callback*/ + + MQTTAsync_updateConnectOptions* updateConnectOptions; + void* updateConnectOptions_context; + + /* Each time connect is called, we store the options that were used. These are reused in + any call to reconnect, or an automatic reconnect attempt */ + MQTTAsync_command connect; /* Connect operation properties */ + MQTTAsync_command disconnect; /* Disconnect operation properties */ + MQTTAsync_command* pending_write; /* Is there a socket write pending? */ + + List* responses; + unsigned int command_seqno; + + MQTTPacket* pack; + + /* added for offline buffering */ + MQTTAsync_createOptions* createOptions; + int shouldBeConnected; + int noBufferedMessages; /* the current number of buffered (publish) messages for this client */ + + /* added for automatic reconnect */ + int automaticReconnect; + int minRetryInterval; + int maxRetryInterval; + int serverURIcount; + char** serverURIs; + int connectTimeout; + + int currentInterval; + int currentIntervalBase; + START_TIME_TYPE lastConnectionFailedTime; + int retrying; + int reconnectNow; + + /* MQTT V5 properties */ + MQTTProperties* connectProps; + MQTTProperties* willProps; + +} MQTTAsyncs; + +typedef struct +{ + MQTTAsync_command command; + MQTTAsyncs* client; + unsigned int seqno; /* only used on restore */ + int not_restored; + char* key; /* if not_restored, this holds the key */ +} MQTTAsync_queuedCommand; + +void MQTTAsync_lock_mutex(mutex_type amutex); +void MQTTAsync_unlock_mutex(mutex_type amutex); +void MQTTAsync_terminate(void); +#if !defined(NO_PERSISTENCE) +int MQTTAsync_restoreCommands(MQTTAsyncs* client); +#endif +int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size); +void MQTTAsync_emptyMessageQueue(Clients* client); +void MQTTAsync_freeResponses(MQTTAsyncs* m); +void MQTTAsync_freeCommands(MQTTAsyncs* m); +int MQTTAsync_unpersistCommandsAndMessages(Clients* c); +void MQTTAsync_closeSession(Clients* client, enum MQTTReasonCodes reasonCode, MQTTProperties* props); +int MQTTAsync_disconnect1(MQTTAsync handle, const MQTTAsync_disconnectOptions* options, int internal); +int MQTTAsync_assignMsgId(MQTTAsyncs* m); +int MQTTAsync_getNoBufferedMessages(MQTTAsyncs* m); +void MQTTAsync_writeComplete(int socket, int rc); +void setRetryLoopInterval(int keepalive); + +#if defined(_WIN32) || defined(_WIN64) +#else +#define WINAPI +#endif + +thread_return_type WINAPI MQTTAsync_sendThread(void* n); +thread_return_type WINAPI MQTTAsync_receiveThread(void* n); + +#endif /* MQTTASYNCUTILS_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTClient.h new file mode 100644 index 0000000..da61357 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTClient.h @@ -0,0 +1,1945 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - remove const from eyecatchers #168 + *******************************************************************************/ + +/** + * @cond MQTTClient_internal + * @mainpage MQTT Client Library Internals + * In the beginning there was one MQTT C client library, MQTTClient, as implemented in MQTTClient.c + * This library was designed to be easy to use for applications which didn't mind if some of the calls + * blocked for a while. For instance, the MQTTClient_connect call will block until a successful + * connection has completed, or a connection has failed, which could be as long as the "connection + * timeout" interval, whose default is 30 seconds. + * + * However in mobile devices and other windowing environments, blocking on the GUI thread is a bad + * thing as it causes the user interface to freeze. Hence a new API, MQTTAsync, implemented + * in MQTTAsync.c, was devised. There are no blocking calls in this library, so it is well suited + * to GUI and mobile environments, at the expense of some extra complexity. + * + * Both libraries are designed to be sparing in the use of threads. So multiple client objects are + * handled by one or two threads, with a select call in Socket_getReadySocket(), used to determine + * when a socket has incoming data. This API is thread safe: functions may be called by multiple application + * threads, with the exception of ::MQTTClient_yield and ::MQTTClient_receive, which are intended + * for single threaded environments only. + * + * @endcond + * @cond MQTTClient_main + * @mainpage MQTT Client library for C + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An MQTT client library in C. + * + * These pages describe the original more synchronous API which might be + * considered easier to use. Some of the calls will block. For the new + * totally asynchronous API where no calls block, which is especially suitable + * for use in windowed environments, see the + * MQTT C Client Asynchronous API Documentation. + * The MQTTClient API is not thread safe, whereas the MQTTAsync API is. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions if multi-threaded (asynchronous mode) + * operation is being used (see @ref async).
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref pubsync
  • + *
  • @ref pubasync
  • + *
  • @ref subasync
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref callbacks
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENT_H) +#define MQTTCLIENT_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTCLIENT_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTCLIENT_FAILURE -1 + +/* error code -2 is MQTTCLIENT_PERSISTENCE_ERROR */ + +/** + * Return code: The client is disconnected. + */ +#define MQTTCLIENT_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTCLIENT_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTCLIENT_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTCLIENT_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTCLIENT_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTCLIENT_BAD_STRUCTURE -8 +/** + * Return code: A QoS value that falls outside of the acceptable range (0,1,2) + */ +#define MQTTCLIENT_BAD_QOS -9 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTCLIENT_SSL_NOT_SUPPORTED -10 + /** + * Return code: unrecognized MQTT version + */ + #define MQTTCLIENT_BAD_MQTT_VERSION -11 +/** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + */ +#define MQTTCLIENT_BAD_PROTOCOL -14 + /** + * Return code: option not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic on connect + */ + #define MQTTCLIENT_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 + /** + * MQTT version to connect with: 5 + */ + #define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTClient_init_options; + +#define MQTTClient_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library (0) + */ +LIBMQTT_API void MQTTClient_global_init(MQTTClient_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTClient_create(). + */ +typedef void* MQTTClient; +/** + * A value representing an MQTT message. A delivery token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTClient_publish(), + * MQTTClient_publishMessage(), + * MQTTClient_deliveryComplete(), + * MQTTClient_waitForCompletion() and + * MQTTClient_getPendingDeliveryTokens()). + */ +typedef int MQTTClient_deliveryToken; +typedef int MQTTClient_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTClient_publishMessage(), + * MQTTClient_publish(), MQTTClient_receive(), MQTTClient_freeMessage() + * and MQTTClient_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. + */ + int dup; + /** The message identifier is normally reserved for internal use by the + * MQTT client and server. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTClient_message; + +#define MQTTClient_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTClient_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTClient_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTClient_freeMessage must be called. + * To free the topic name storage, ::MQTTClient_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTClient_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTClient_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages. The function is registered with the + * client library by passing it as an argument to MQTTClient_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note:MQTTClient_deliveryComplete() is not called when messages are + * published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken dt); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTClient_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_connectionLost(void* context, char* cause); + +/** + * This function sets the callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Calling MQTTClient_setCallbacks() puts the + * client into multi-threaded mode. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. See @ref async for more information. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTClient_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTClient_messageArrived() callback + * function. This callback function must be set when you call + * MQTTClient_setCallbacks(), as otherwise there would be nowhere to deliver + * any incoming messages. + * @param dc A pointer to an MQTTClient_deliveryComplete() callback + * function. You can set this to NULL if your application publishes + * synchronously or if you do not want to check for successful delivery. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl, + MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc); + + +/** + * This is a callback function, which will be called when the a disconnect + * packet is received from the server. This applies to MQTT V5 and above only. + * @param context A pointer to the context value originally passed to + * ::MQTTClient_setDisconnected(), which contains any application-specific context. + * @param properties The MQTT V5 properties received with the disconnect, if any. + * @param reasonCode The MQTT V5 reason code received with the disconnect. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTClient_disconnected() callback function for a client. This will be called + * if a disconnect packet is received from the server. Only valid for MQTT V5 and above. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTClient_disconnected() callback + * function. NULL removes the callback setting. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setDisconnected(MQTTClient handle, void* context, MQTTClient_disconnected* co); + +/** + * This is a callback function, the MQTT V5 version of MQTTClient_deliveryComplete(). + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the completed delivery of messages. + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note: It is not called when messages are published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + * @param packet_type the last received packet type for this completion. For QoS 1 + * always PUBACK. For QoS 2 could be PUBREC or PUBCOMP. + * @param properties the MQTT V5 properties returned with the last packet from the server + * @param reasonCode the reason code returned from the server + */ +typedef void MQTTClient_published(void* context, int dt, int packet_type, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +LIBMQTT_API int MQTTClient_setPublished(MQTTClient handle, void* context, MQTTClient_published* co); + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTClient_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; +} MQTTClient_createOptions; + +#define MQTTClient_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, MQTTVERSION_DEFAULT } + +/** + * A version of :MQTTClient_create() with additional options. + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp or ssl. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @param options additional options for the create. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_createWithOptions(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTClient_createOptions* options); + +/** + * MQTTClient_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTClient_willOptions + * structure is passed in the MQTTClient_connectOptions structure used in the + * MQTTClient_connect() call that connects the client to the server. The pointer + * to MQTTClient_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 means there is no binary payload option + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload in string form. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTClient_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTClient_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTClient_willOptions; + +#define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTClient_SSLOptions; + +#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** + * MQTTClient_libraryInfo is used to store details relating to the currently used + * library such as the version in use, the time it was built and relevant openSSL + * options. + * There is one static instance of this struct in MQTTClient.c + */ + +typedef struct +{ + const char* name; + const char* value; +} MQTTClient_nameValue; + +/** + * This function returns version information about the library. + * no trace information will be returned. + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTClient_nameValue* MQTTClient_getVersionInfo(void); + +/** + * MQTTClient_connectOptions defines several settings that control the way the + * client connects to an MQTT server. + * + * Note: Default values are not defined for members of + * MQTTClient_connectOptions so it is good practice to specify all settings. + * If the MQTTClient_connectOptions structure is defined as an automatic + * variable, all members are set to random values and thus must be set by the + * client application. If the MQTTClient_connectOptions structure is defined + * as a static variable, initialization (in compliant compilers) sets all + * values to 0 (NULL for pointers). A #keepAliveInterval setting of 0 prevents + * correct operation of the client and so you must at least set a value + * for #keepAliveInterval. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3, 4, 5, 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no returned values + * 4 signifies no binary password option + * 5 signifies no maxInflightMessages and cleanstart + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTClient_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This is a boolean value that controls how many messages can be in-flight + * simultaneously. Setting reliable to true means that a published + * message must be completed (acknowledgements received) before another + * can be sent. Attempts to publish additional messages receive an + * ::MQTTCLIENT_MAX_MESSAGES_INFLIGHT return code. Setting this flag to + * false allows up to 10 messages to be in-flight. This can increase + * overall throughput in some circumstances. + */ + int reliable; + /** + * This is a pointer to an MQTTClient_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTClient_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTClient_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTClient_SSLOptions* ssl; + /** + * The number of entries in the optional serverURIs array. Defaults to 0. + */ + int serverURIcount; + /** + * An optional array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * If this list is empty (the default), the server URI specified on MQTTClient_create() + * is used. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + * MQTTVERSION_5 (5) = only try version 5.0 + */ + int MQTTVersion; + /** + * Returned from the connect when the MQTT version used to connect is 3.1.1 + */ + struct + { + const char* serverURI; /**< the serverURI connected to */ + int MQTTVersion; /**< the MQTT version used to connect with */ + int sessionPresent; /**< if the MQTT version is 3.1.1, the value of sessionPresent returned in the connack */ + } returned; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct + { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /** + * The maximum number of messages in flight + */ + int maxInflightMessages; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * HTTP headers for websockets + */ + const MQTTClient_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTClient_connectOptions; + +#define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +/** + * This function attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @return ::MQTTCLIENT_SUCCESS if the client successfully connects to the + * server. An error code is returned if the client was unable to connect to + * the server. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options); + +/** MQTT version 5.0 response information */ +typedef struct MQTTResponse +{ + int version; /* the version number of this structure */ + enum MQTTReasonCodes reasonCode; /* the MQTT 5.0 reason code returned */ + int reasonCodeCount; /* the number of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + enum MQTTReasonCodes* reasonCodes; /* a list of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + MQTTProperties* properties; /* optionally, the MQTT 5.0 properties returned */ +} MQTTResponse; + +#define MQTTResponse_initializer {1, MQTTREASONCODE_SUCCESS, 0, NULL, NULL} + +/** + * Frees the storage associated with the MQTT response. + * @param response the response structure to be freed + */ +LIBMQTT_API void MQTTResponse_free(MQTTResponse response); + +/** + * Attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using MQTT version 5.0 and the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @param connectProperties the MQTT 5.0 connect properties to use + * @param willProperties the MQTT 5.0 properties to set on the will message + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_connect5(MQTTClient handle, MQTTClient_connectOptions* options, + MQTTProperties* connectProperties, MQTTProperties* willProperties); + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTClient_connectOptions.cleansession and MQTTClient_connect()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param timeout The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTClient_disconnect(MQTTClient handle, int timeout); + +LIBMQTT_API int MQTTClient_disconnect5(MQTTClient handle, int timeout, enum MQTTReasonCodes reason, MQTTProperties* props); + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTClient_isConnected(MQTTClient handle); + + +/* Subscribe is synchronous. QoS list parameter is changed on return to granted QoSs. + Returns return code, MQTTCLIENT_SUCCESS == success, non-zero some sort of error (TBD) */ + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTClient_subscribe(MQTTClient handle, const char* topic, int qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribe5(MQTTClient handle, const char* topic, int qos, + MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribeMany5(MQTTClient handle, int count, char* const* topic, + int* qos, MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @return ::MQTTCLIENT_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTClient_unsubscribe(MQTTClient handle, const char* topic); + +/** + * This function attempts to remove an existing subscription made by the + * specified client using MQTT 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribe5(MQTTClient handle, const char* topic, MQTTProperties* props); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @return ::MQTTCLIENT_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client using MQTT version 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribeMany5(MQTTClient handle, int count, char* const* topic, MQTTProperties* props); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publishMessage()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publish(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, int qos, int retained, + MQTTClient_deliveryToken* dt); + +/** + * Attempts to publish a message to a given topic using MQTT version 5.0 (see also + * MQTTClient_publishMessage5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param properties the MQTT 5.0 properties to be used + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publish5(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, + int qos, int retained, MQTTProperties* properties, MQTTClient_deliveryToken* dt); +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publishMessage(MQTTClient handle, const char* topicName, MQTTClient_message* msg, MQTTClient_deliveryToken* dt); + + +/** + * Attempts to publish a message to the given topic using MQTT version 5.0 + * (see also + * MQTTClient_publish5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char* topicName, MQTTClient_message* msg, + MQTTClient_deliveryToken* dt); + +/** + * This function is called by the client application to synchronize execution + * of the main thread with completed publication of a message. When called, + * MQTTClient_waitForCompletion() blocks execution until the message has been + * successful delivered or the specified timeout has expired. See @ref async. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param dt The ::MQTTClient_deliveryToken that represents the message being + * tested for successful delivery. Delivery tokens are issued by the + * publishing functions MQTTClient_publish() and MQTTClient_publishMessage(). + * @param timeout The maximum time to wait in milliseconds. + * @return ::MQTTCLIENT_SUCCESS if the message was successfully delivered. + * An error code is returned if the timeout expires or there was a problem + * checking the token. + */ +LIBMQTT_API int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken dt, unsigned long timeout); + + +/** + * This function sets a pointer to an array of delivery tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param tokens The address of a pointer to an ::MQTTClient_deliveryToken. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTCLIENT_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTClient_getPendingDeliveryTokens(MQTTClient handle, MQTTClient_deliveryToken **tokens); + +/** + * When implementing a single-threaded client, call this function periodically + * to allow processing of message retries and to send MQTT keepalive pings. + * If the application is calling MQTTClient_receive() regularly, then it is + * not necessary to call this function. + */ +LIBMQTT_API void MQTTClient_yield(void); + +/** + * This function performs a synchronous receive of incoming messages. It should + * be used only when the client application has not set callback methods to + * support asynchronous receipt of messages (see @ref async and + * MQTTClient_setCallbacks()). Using this function allows a single-threaded + * client subscriber application to be written. When called, this function + * blocks until the next message arrives or the specified timeout expires + *(see also MQTTClient_yield()). + * + * Important note: The application must free() the memory allocated + * to the topic and the message when processing is complete (see + * MQTTClient_freeMessage()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The address of a pointer to a topic. This function + * allocates the memory for the topic and returns it to the application + * by setting topicName to point to the topic. + * @param topicLen The length of the topic. If the return code from this + * function is ::MQTTCLIENT_TOPICNAME_TRUNCATED, the topic contains embedded + * NULL characters and the full topic should be retrieved by using + * topicLen. + * @param message The address of a pointer to the received message. This + * function allocates the memory for the message and returns it to the + * application by setting message to point to the received message. + * The pointer is set to NULL if the timeout expires. + * @param timeout The length of time to wait for a message in milliseconds. + * @return ::MQTTCLIENT_SUCCESS or ::MQTTCLIENT_TOPICNAME_TRUNCATED if a + * message is received. ::MQTTCLIENT_SUCCESS can also indicate that the + * timeout expired, in which case message is NULL. An error code is + * returned if there was a problem trying to receive a message. + */ +LIBMQTT_API int MQTTClient_receive(MQTTClient handle, char** topicName, int* topicLen, MQTTClient_message** message, + unsigned long timeout); + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTClient_free() library function. + * @param msg The address of a pointer to the ::MQTTClient_message structure + * to be freed. + */ +LIBMQTT_API void MQTTClient_freeMessage(MQTTClient_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client libary and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTClient_free(void* ptr); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTClient_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTClient + * structure to be freed. + */ +LIBMQTT_API void MQTTClient_destroy(MQTTClient* handle); + + +enum MQTTCLIENT_TRACE_LEVELS +{ + MQTTCLIENT_TRACE_MAXIMUM = 1, + MQTTCLIENT_TRACE_MEDIUM, + MQTTCLIENT_TRACE_MINIMUM, + MQTTCLIENT_TRACE_PROTOCOL, + MQTTCLIENT_TRACE_ERROR, + MQTTCLIENT_TRACE_SEVERE, + MQTTCLIENT_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTClient_setTraceLevel(enum MQTTCLIENT_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTClient_traceCallback(enum MQTTCLIENT_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTClient_setTraceCallback(MQTTClient_traceCallback* callback); + +/** + * Sets the timeout value for un/subscribe commands when waiting for the un/suback response from + * the server. Values less than 5000 are not allowed. + * @param handle A valid client handle from a successful call to MQTTClient_create(). + * @param milliSeconds the maximum number of milliseconds to wait + * @return MQTTCLIENT_SUCCESS or MQTTCLIENT_FAILURE + */ +LIBMQTT_API int MQTTClient_setCommandTimeout(MQTTClient handle, unsigned long milliSeconds); + +/** + * Returns a pointer to the string representation of the error or NULL. + * + * Do not free after use. Returns NULL if the error code is unknown. + */ +LIBMQTT_API const char* MQTTClient_strerror(int code); + +#if defined(__cplusplus) + } +#endif + +#endif + +/*! + * @cond MQTTClient_main + * @page async Asynchronous vs synchronous client applications + * This client library supports two modes of operation. These are referred to + * as synchronous and asynchronous modes. If your application + * calls MQTTClient_setCallbacks(), this puts the client into asynchronous + * mode, otherwise it operates in synchronous mode. + * + * In synchronous mode, the client application runs on a single thread. + * Messages are published using the MQTTClient_publish() and + * MQTTClient_publishMessage() functions. To determine that a QoS1 or QoS2 + * (see @ref qos) message has been successfully delivered, the application + * must call the MQTTClient_waitForCompletion() function. An example showing + * synchronous publication is shown in @ref pubsync. Receiving messages in + * synchronous mode uses the MQTTClient_receive() function. Client applications + * must call either MQTTClient_receive() or MQTTClient_yield() relatively + * frequently in order to allow processing of acknowledgements and the MQTT + * "pings" that keep the network connection to the server alive. + * + * In asynchronous mode, the client application runs on several threads. The + * main program calls functions in the client library to publish and subscribe, + * just as for the synchronous mode. Processing of handshaking and maintaining + * the network connection is performed in the background, however. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTClient_setCallbacks() (see MQTTClient_messageArrived(), + * MQTTClient_connectionLost() and MQTTClient_deliveryComplete()). + * This API is not thread safe however - it is not possible to call it from multiple + * threads without synchronization. You can use the MQTTAsync API for that. + * + * @page callbacks Callbacks + * You must not call a function from this API from within a callback otherwise + * a deadlock might result. The only exception to this is the ability to call + * connect within the connection lost callback, to allow a reconnect. + * + * When using MQTT 5.0, you can also call connect from within the disconnected + * callback, which is invoked when the MQTT server sends a disconnect packet. + * This server behaviour is allowed in MQTT 5.0, but not in MQTT 3.1.1, so the + * disconnected callback will never be invoked if you use MQTT 3.1.1. + * + * In particular, you must make a publish call within the message arrived callback. + * These restrictions are all lifted in the + * MQTTAsync API. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, or receive not called, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * It is up to the application to protect against this situation. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTClient_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTClient_subscribe() and MQTTClient_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page pubsync Synchronous publication example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for up to %d seconds for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID); + rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); + printf("Message with delivery token %d delivered\n", token); + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + printf("Failed to disconnect, return code %d\n", rc); + MQTTClient_destroy(&client); + return rc; +} + + * @endcode + * + * @page pubasync Asynchronous publication example +@code{.c} +#include +#include +#include +#include "MQTTClient.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + deliveredtoken = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (deliveredtoken != token) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } + +destroy_exit: + MQTTClient_destroy(&client); + +exit: + return rc; +} + + * @endcode + * @page subasync Asynchronous subscription example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +volatile MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + if ((rc = MQTTClient_subscribe(client, TOPIC, QOS)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to subscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + int ch; + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + if ((rc = MQTTClient_unsubscribe(client, TOPIC)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to unsubscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } +destroy_exit: + MQTTClient_destroy(&client); +exit: + return rc; +} + + * @endcode + * @page tracing Tracing + * + * Runtime tracing is controlled by environment variables. + * + * Tracing is switched on by setting MQTT_C_CLIENT_TRACE. A value of ON, or stdout, prints to + * stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTClientPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTClientPersistence.h new file mode 100644 index 0000000..d3caae4 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTClientPersistence.h @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** + * @file + * \brief This structure represents a persistent data store, used to store + * outbound and inbound messages, in order to achieve reliable messaging. + * + * The MQTT Client persists QoS1 and QoS2 messages in order to meet the + * assurances of delivery associated with these @ref qos levels. The messages + * are saved in persistent storage + * The type and context of the persistence implementation are specified when + * the MQTT client is created (see MQTTClient_create()). The default + * persistence type (::MQTTCLIENT_PERSISTENCE_DEFAULT) uses a file system-based + * persistence mechanism. The persistence_context argument passed to + * MQTTClient_create() when using the default peristence is a string + * representing the location of the persistence directory. If the context + * argument is NULL, the working directory will be used. + * + * To use memory-based persistence, an application passes + * ::MQTTCLIENT_PERSISTENCE_NONE as the persistence_type to + * MQTTClient_create(). This can lead to message loss in certain situations, + * but can be appropriate in some cases (see @ref qos). + * + * Client applications can provide their own persistence mechanism by passing + * ::MQTTCLIENT_PERSISTENCE_USER as the persistence_type. To implement a + * custom persistence mechanism, the application must pass an initialized + * ::MQTTClient_persistence structure as the persistence_context + * argument to MQTTClient_create(). + * + * If the functions defined return an ::MQTTCLIENT_PERSISTENCE_ERROR then the + * state of the persisted data should remain as it was prior to the function + * being called. For example, if Persistence_put() returns + * ::MQTTCLIENT_PERSISTENCE_ERROR, then it is assumed tha tthe persistent store + * does not contain the data that was passed to the function. Similarly, if + * Persistence_remove() returns ::MQTTCLIENT_PERSISTENCE_ERROR then it is + * assumed that the data to be removed is still held in the persistent store. + * + * It is up to the persistence implementation to log any error information that + * may be required to diagnose a persistence mechanism failure. + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENTPERSISTENCE_H) +#define MQTTCLIENTPERSISTENCE_H +/* +/// @endcond +*/ + +/** + * This persistence_type value specifies the default file system-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_DEFAULT 0 +/** + * This persistence_type value specifies a memory-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_NONE 1 +/** + * This persistence_type value specifies an application-specific + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_USER 2 + +/** + * Application-specific persistence functions must return this error code if + * there is a problem executing the function. + */ +#define MQTTCLIENT_PERSISTENCE_ERROR -2 + +/** + * @brief Initialize the persistent store. + * + * Either open the existing persistent store for this client ID or create a new + * one if one doesn't exist. If the persistent store is already open, return + * without taking any action. + * + * An application can use the same client identifier to connect to many + * different servers. The clientid in conjunction with the + * serverURI uniquely identifies the persistence store required. + * + * @param handle The address of a pointer to a handle for this persistence + * implementation. This function must set handle to a valid reference to the + * persistence following a successful return. + * The handle pointer is passed as an argument to all the other + * persistence functions. It may include the context parameter and/or any other + * data for use by the persistence functions. + * @param clientID The client identifier for which the persistent store should + * be opened. + * @param serverURI The connection string specified when the MQTT client was + * created (see MQTTClient_create()). + * @param context A pointer to any data required to initialize the persistent + * store (see ::MQTTClient_persistence). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_open)(void** handle, const char* clientID, const char* serverURI, void* context); + +/** + * @brief Close the persistent store referred to by the handle. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_close)(void* handle); + +/** + * @brief Put the specified data into the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string used as the key for the data to be put in the store. The + * key is later used to retrieve data from the store with Persistence_get(). + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers associated with + * this key. + * @param buflens An array of lengths of the data buffers. buflen[n] + * gives the length of buffer[n]. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_put)(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); + +/** + * @brief Retrieve the specified data from the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be retrieved. This is + * the same key used to save the data to the store with Persistence_put(). + * @param buffer The address of a pointer to a buffer. This function sets the + * pointer to point at the retrieved data, if successful. + * @param buflen The address of an int that is set to the length of + * buffer by this function if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_get)(void* handle, char* key, char** buffer, int* buflen); + +/** + * @brief Remove the data for the specified key from the store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be removed from the + * store. This is the same key used to save the data to the store with + * Persistence_put(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_remove)(void* handle, char* key); + +/** + * @brief Returns the keys in this persistent data store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param keys The address of a pointer to pointers to strings. Assuming + * successful execution, this function allocates memory to hold the returned + * keys (strings used to store the data with Persistence_put()). It also + * allocates memory to hold an array of pointers to these strings. keys + * is set to point to the array of pointers to strings. + * @param nkeys A pointer to the number of keys in this persistent data store. + * This function sets the number of keys, if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_keys)(void* handle, char*** keys, int* nkeys); + +/** + * @brief Clears the persistence store, so that it no longer contains any + * persisted data. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_clear)(void* handle); + +/** + * @brief Returns whether any data has been persisted using the specified key. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key The string to be tested for existence in the store. + * @return Return 0 if the key was found in the store, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_containskey)(void* handle, char* key); + +/** + * @brief A structure containing the function pointers to a persistence + * implementation and the context or state that will be shared across all + * the persistence functions. + */ +typedef struct { + /** + * A pointer to any data required to initialize the persistent store. + */ + void* context; + /** + * A function pointer to an implementation of Persistence_open(). + */ + Persistence_open popen; + /** + * A function pointer to an implementation of Persistence_close(). + */ + Persistence_close pclose; + /** + * A function pointer to an implementation of Persistence_put(). + */ + Persistence_put pput; + /** + * A function pointer to an implementation of Persistence_get(). + */ + Persistence_get pget; + /** + * A function pointer to an implementation of Persistence_remove(). + */ + Persistence_remove premove; + /** + * A function pointer to an implementation of Persistence_keys(). + */ + Persistence_keys pkeys; + /** + * A function pointer to an implementation of Persistence_clear(). + */ + Persistence_clear pclear; + /** + * A function pointer to an implementation of Persistence_containskey(). + */ + Persistence_containskey pcontainskey; +} MQTTClient_persistence; + + +/** + * A callback which is invoked just before a write to persistence. This can be + * used to transform the data, for instance to encrypt it. + * @param context The context as set in ::MQTTAsync_setBeforePersistenceWrite + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers. + * @param buflens An array of lengths of the data buffers. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_beforeWrite(void* context, int bufcount, char* buffers[], int buflens[]); + + +/** + * A callback which is invoked just after a read from persistence. This can be + * used to transform the data, for instance to decrypt it. + * @param context The context as set in ::MQTTAsync_setAfterPersistenceRead + * @param buffer The address of a pointer to a buffer. + * @param buflen The address of an int that is the length of the buffer. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_afterRead(void* context, char** buffer, int* buflen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTExportDeclarations.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTExportDeclarations.h new file mode 100644 index 0000000..d492ef1 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTExportDeclarations.h @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 Andreas Walter + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Andreas Walter - initially moved export declarations into separate fle + *******************************************************************************/ + +#if !defined(EXPORTDECLARATIONS_H) +#define EXPORTDECLARATIONS_H + +#if defined(_WIN32) || defined(_WIN64) +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __declspec(dllexport) +# elif defined(PAHO_MQTT_IMPORTS) +# define LIBMQTT_API __declspec(dllimport) +# else +# define LIBMQTT_API +# endif +#else +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __attribute__ ((visibility ("default"))) +# else +# define LIBMQTT_API extern +# endif +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPacket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPacket.h new file mode 100644 index 0000000..658404a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPacket.h @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - big endian Linux reversed definition + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKET_H) +#define MQTTPACKET_H + +#include "Socket.h" +#if defined(OPENSSL) +#include "SSLSocket.h" +#endif +#include "LinkedList.h" +#include "Clients.h" + +typedef unsigned int bool; +typedef void* (*pf)(int, unsigned char, char*, size_t); + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" + +enum errors +{ + MQTTPACKET_BAD = -4, + MQTTPACKET_BUFFER_TOO_SHORT = -2, + MQTTPACKET_READ_ERROR = -1, + MQTTPACKET_READ_COMPLETE +}; + + +enum msgTypes +{ + CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, + PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, + PINGREQ, PINGRESP, DISCONNECT, AUTH +}; + +#if defined(__linux__) +#include +#if __BYTE_ORDER == __BIG_ENDIAN + #define REVERSED 1 +#endif +#endif + +/** + * Bitfields for the MQTT header byte. + */ +typedef union +{ + /*unsigned*/ char byte; /**< the whole byte */ +#if defined(REVERSED) + struct + { + unsigned int type : 4; /**< message type nibble */ + bool dup : 1; /**< DUP flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool retain : 1; /**< retained flag bit */ + } bits; +#else + struct + { + bool retain : 1; /**< retained flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool dup : 1; /**< DUP flag bit */ + unsigned int type : 4; /**< message type nibble */ + } bits; +#endif +} Header; + + +/** + * Data for a connect packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connect flags */ +#if defined(REVERSED) + struct + { + bool username : 1; /**< 3.1 user name */ + bool password : 1; /**< 3.1 password */ + bool willRetain : 1; /**< will retain setting */ + unsigned int willQoS : 2; /**< will QoS value */ + bool will : 1; /**< will flag */ + bool cleanstart : 1; /**< cleansession flag */ + int : 1; /**< unused */ + } bits; +#else + struct + { + int : 1; /**< unused */ + bool cleanstart : 1; /**< cleansession flag */ + bool will : 1; /**< will flag */ + unsigned int willQoS : 2; /**< will QoS value */ + bool willRetain : 1; /**< will retain setting */ + bool password : 1; /**< 3.1 password */ + bool username : 1; /**< 3.1 user name */ + } bits; +#endif + } flags; /**< connect flags byte */ + + char *Protocol, /**< MQTT protocol name */ + *clientID, /**< string client id */ + *willTopic, /**< will topic */ + *willMsg; /**< will payload */ + + int keepAliveTimer; /**< keepalive timeout value in seconds */ + unsigned char version; /**< MQTT version number */ +} Connect; + + +/** + * Data for a connack packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connack flags */ +#if defined(REVERSED) + struct + { + unsigned int reserved : 7; /**< message type nibble */ + bool sessionPresent : 1; /**< was a session found on the server? */ + } bits; +#else + struct + { + bool sessionPresent : 1; /**< was a session found on the server? */ + unsigned int reserved : 7; /**< message type nibble */ + } bits; +#endif + } flags; /**< connack flags byte */ + unsigned char rc; /**< connack reason code */ + unsigned int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Connack; + + +/** + * Data for a packet with header only. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ +} MQTTPacket; + + +/** + * Data for a suback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* qoss; /**< list of granted QoSs (MQTT 3/4) / reason codes (MQTT 5) */ +} Suback; + + +/** + * Data for an MQTT V5 unsuback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* reasonCodes; /**< list of reason codes */ +} Unsuback; + + +/** + * Data for a publish packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + char* topic; /**< topic string */ + int topiclen; + int msgId; /**< MQTT message id */ + char* payload; /**< binary payload, length delimited */ + int payloadlen; /**< payload length */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + uint8_t mask[4]; /**< the websockets mask the payload is masked with, if any */ +} Publish; + + +/** + * Data for one of the ack packets. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + unsigned char rc; /**< MQTT 5 reason code */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Ack; + +typedef Ack Puback; +typedef Ack Pubrec; +typedef Ack Pubrel; +typedef Ack Pubcomp; + +int MQTTPacket_encode(char* buf, size_t length); +int MQTTPacket_decode(networkHandles* net, size_t* value); +int readInt(char** pptr); +char* readUTF(char** pptr, char* enddata); +unsigned char readChar(char** pptr); +void writeChar(char** pptr, char c); +void writeInt(char** pptr, int anInt); +void writeUTF(char** pptr, const char* string); +void writeData(char** pptr, const void* data, int datalen); + +const char* MQTTPacket_name(int ptype); + +void* MQTTPacket_Factory(int MQTTVersion, networkHandles* net, int* error); +int MQTTPacket_send(networkHandles* net, Header header, char* buffer, size_t buflen, int free, int MQTTVersion); +int MQTTPacket_sends(networkHandles* net, Header header, PacketBuffers* buffers, int MQTTVersion); + +void* MQTTPacket_header_only(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +int MQTTPacket_send_disconnect(Clients* client, enum MQTTReasonCodes reason, MQTTProperties* props); + +void* MQTTPacket_publish(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freePublish(Publish* pack); +int MQTTPacket_send_publish(Publish* pack, int dup, int qos, int retained, networkHandles* net, const char* clientID); +int MQTTPacket_send_puback(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +void MQTTPacket_freeAck(Ack* pack); +void MQTTPacket_freeSuback(Suback* pack); +void MQTTPacket_freeUnsuback(Unsuback* pack); +int MQTTPacket_send_pubrec(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubrel(int MQTTVersion, int msgid, int dup, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubcomp(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); + +void MQTTPacket_free_packet(MQTTPacket* pack); + +void writeInt4(char** pptr, int anInt); +int readInt4(char** pptr); +void writeMQTTLenString(char** pptr, MQTTLenString lenstring); +int MQTTLenStringRead(MQTTLenString* lenstring, char** pptr, char* enddata); +int MQTTPacket_VBIlen(int rem_len); +int MQTTPacket_decodeBuf(char* buf, unsigned int* value); + +#include "MQTTPacketOut.h" + +#endif /* MQTTPACKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPacketOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPacketOut.h new file mode 100644 index 0000000..d962554 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPacketOut.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKETOUT_H) +#define MQTTPACKETOUT_H + +#include "MQTTPacket.h" + +int MQTTPacket_send_connect(Clients* client, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +void* MQTTPacket_connack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freeConnack(Connack* pack); + +int MQTTPacket_send_pingreq(networkHandles* net, const char* clientID); + +int MQTTPacket_send_subscribe(List* topics, List* qoss, MQTTSubscribe_options* opts, MQTTProperties* props, + int msgid, int dup, Clients* client); +void* MQTTPacket_suback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +int MQTTPacket_send_unsubscribe(List* topics, MQTTProperties* props, int msgid, int dup, Clients* client); +void* MQTTPacket_unsuback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPersistence.h new file mode 100644 index 0000000..ed2e0ce --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPersistence.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - async client updates + * Ian Craggs - fix for bug 432903 - queue persistence + * Ian Craggs - MQTT V5 updates + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCE_H) +#define MQTTPERSISTENCE_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include "Clients.h" +#include "MQTTProperties.h" + +/** Stem of the key for a sent PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_PUBLISH_SENT "s-" +/** Stem of the key for a sent PUBREL */ +#define PERSISTENCE_PUBREL "sc-" +/** Stem of the key for a received PUBLISH QoS2 */ +#define PERSISTENCE_PUBLISH_RECEIVED "r-" + +/** Stem of the key for a sent MQTT V5 PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_V5_PUBLISH_SENT "s5-" +/** Stem of the key for a sent MQTT V5 PUBREL */ +#define PERSISTENCE_V5_PUBREL "sc5-" +/** Stem of the key for a received MQTT V5 PUBLISH QoS2 */ +#define PERSISTENCE_V5_PUBLISH_RECEIVED "r5-" + +/** Stem of the key for an async client command */ +#define PERSISTENCE_COMMAND_KEY "c-" +/** Stem of the key for an MQTT V5 async client command */ +#define PERSISTENCE_V5_COMMAND_KEY "c5-" +/** Stem of the key for an client incoming message queue */ +#define PERSISTENCE_QUEUE_KEY "q-" +/** Stem of the key for an MQTT V5 incoming message queue */ +#define PERSISTENCE_V5_QUEUE_KEY "q5-" +/** Maximum length of a stem for a persistence key */ +#define PERSISTENCE_MAX_STEM_LENGTH 3 +/** Maximum allowed length of a persistence key */ +#define PERSISTENCE_MAX_KEY_LENGTH 9 +/** Maximum size of an integer sequence number appended to a persistence key */ +#define PERSISTENCE_SEQNO_LIMIT 1000000 /*10^(PERSISTENCE_MAX_KEY_LENGTH - PERSISTENCE_MAX_STEM_LENGTH)*/ + +int MQTTPersistence_create(MQTTClient_persistence** per, int type, void* pcontext); +int MQTTPersistence_initialize(Clients* c, const char* serverURI); +int MQTTPersistence_close(Clients* c); +int MQTTPersistence_clear(Clients* c); +int MQTTPersistence_restorePackets(Clients* c); +void* MQTTPersistence_restorePacket(int MQTTVersion, char* buffer, size_t buflen); +void MQTTPersistence_insertInOrder(List* list, void* content, size_t size); +int MQTTPersistence_putPacket(int socket, char* buf0, size_t buf0len, int count, + char** buffers, size_t* buflens, int htype, int msgId, int scr, int MQTTVersion); +int MQTTPersistence_remove(Clients* c, char* type, int qos, int msgId); +void MQTTPersistence_wrapMsgID(Clients *c); + +typedef struct +{ + char struct_id[4]; + int struct_version; + int payloadlen; + void* payload; + int qos; + int retained; + int dup; + int msgid; + MQTTProperties properties; +} MQTTPersistence_message; + +typedef struct +{ + MQTTPersistence_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} MQTTPersistence_qEntry; + +int MQTTPersistence_unpersistQueueEntry(Clients* client, MQTTPersistence_qEntry* qe); +int MQTTPersistence_persistQueueEntry(Clients* aclient, MQTTPersistence_qEntry* qe); +int MQTTPersistence_restoreMessageQueue(Clients* c); +#ifdef __cplusplus + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPersistenceDefault.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPersistenceDefault.h new file mode 100644 index 0000000..506b4da --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTPersistenceDefault.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCEDEFAULT_H) +#define MQTTPERSISTENCEDEFAULT_H + +/** 8.3 filesystem */ +#define MESSAGE_FILENAME_LENGTH 8 +/** Extension of the filename */ +#define MESSAGE_FILENAME_EXTENSION ".msg" + +/* prototypes of the functions for the default file system persistence */ +int pstopen(void** handle, const char* clientID, const char* serverURI, void* context); +int pstclose(void* handle); +int pstput(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); +int pstget(void* handle, char* key, char** buffer, int* buflen); +int pstremove(void* handle, char* key); +int pstkeys(void* handle, char*** keys, int* nkeys); +int pstclear(void* handle); +int pstcontainskey(void* handle, char* key); + +int pstmkdir(char *pPathname); + +#endif + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProperties.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProperties.h new file mode 100644 index 0000000..81b8e3a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProperties.h @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPROPERTIES_H) +#define MQTTPROPERTIES_H + +#include "MQTTExportDeclarations.h" + +#define MQTT_INVALID_PROPERTY_ID -2 + +/** The one byte MQTT V5 property indicator */ +enum MQTTPropertyCodes { + MQTTPROPERTY_CODE_PAYLOAD_FORMAT_INDICATOR = 1, /**< The value is 1 */ + MQTTPROPERTY_CODE_MESSAGE_EXPIRY_INTERVAL = 2, /**< The value is 2 */ + MQTTPROPERTY_CODE_CONTENT_TYPE = 3, /**< The value is 3 */ + MQTTPROPERTY_CODE_RESPONSE_TOPIC = 8, /**< The value is 8 */ + MQTTPROPERTY_CODE_CORRELATION_DATA = 9, /**< The value is 9 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIER = 11, /**< The value is 11 */ + MQTTPROPERTY_CODE_SESSION_EXPIRY_INTERVAL = 17, /**< The value is 17 */ + MQTTPROPERTY_CODE_ASSIGNED_CLIENT_IDENTIFER = 18,/**< The value is 18 */ + MQTTPROPERTY_CODE_SERVER_KEEP_ALIVE = 19, /**< The value is 19 */ + MQTTPROPERTY_CODE_AUTHENTICATION_METHOD = 21, /**< The value is 21 */ + MQTTPROPERTY_CODE_AUTHENTICATION_DATA = 22, /**< The value is 22 */ + MQTTPROPERTY_CODE_REQUEST_PROBLEM_INFORMATION = 23,/**< The value is 23 */ + MQTTPROPERTY_CODE_WILL_DELAY_INTERVAL = 24, /**< The value is 24 */ + MQTTPROPERTY_CODE_REQUEST_RESPONSE_INFORMATION = 25,/**< The value is 25 */ + MQTTPROPERTY_CODE_RESPONSE_INFORMATION = 26, /**< The value is 26 */ + MQTTPROPERTY_CODE_SERVER_REFERENCE = 28, /**< The value is 28 */ + MQTTPROPERTY_CODE_REASON_STRING = 31, /**< The value is 31 */ + MQTTPROPERTY_CODE_RECEIVE_MAXIMUM = 33, /**< The value is 33*/ + MQTTPROPERTY_CODE_TOPIC_ALIAS_MAXIMUM = 34, /**< The value is 34 */ + MQTTPROPERTY_CODE_TOPIC_ALIAS = 35, /**< The value is 35 */ + MQTTPROPERTY_CODE_MAXIMUM_QOS = 36, /**< The value is 36 */ + MQTTPROPERTY_CODE_RETAIN_AVAILABLE = 37, /**< The value is 37 */ + MQTTPROPERTY_CODE_USER_PROPERTY = 38, /**< The value is 38 */ + MQTTPROPERTY_CODE_MAXIMUM_PACKET_SIZE = 39, /**< The value is 39 */ + MQTTPROPERTY_CODE_WILDCARD_SUBSCRIPTION_AVAILABLE = 40,/**< The value is 40 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIERS_AVAILABLE = 41,/**< The value is 41 */ + MQTTPROPERTY_CODE_SHARED_SUBSCRIPTION_AVAILABLE = 42/**< The value is 241 */ +}; + +/** + * Returns a printable string description of an MQTT V5 property code. + * @param value an MQTT V5 property code. + * @return the printable string description of the input property code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTPropertyName(enum MQTTPropertyCodes value); + +/** The one byte MQTT V5 property type */ +enum MQTTPropertyTypes { + MQTTPROPERTY_TYPE_BYTE, + MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER, + MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER, + MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER, + MQTTPROPERTY_TYPE_BINARY_DATA, + MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING, + MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR +}; + +/** + * Returns the MQTT V5 type code of an MQTT V5 property. + * @param value an MQTT V5 property code. + * @return the MQTT V5 type code of the input property. -1 if the code was not found. + */ +LIBMQTT_API int MQTTProperty_getType(enum MQTTPropertyCodes value); + +/** + * The data for a length delimited string + */ +typedef struct +{ + int len; /**< the length of the string */ + char* data; /**< pointer to the string data */ +} MQTTLenString; + + +/** + * Structure to hold an MQTT version 5 property of any type + */ +typedef struct +{ + enum MQTTPropertyCodes identifier; /**< The MQTT V5 property id. A multi-byte integer. */ + /** The value of the property, as a union of the different possible types. */ + union { + unsigned char byte; /**< holds the value of a byte property type */ + unsigned short integer2; /**< holds the value of a 2 byte integer property type */ + unsigned int integer4; /**< holds the value of a 4 byte integer property type */ + struct { + MQTTLenString data; /**< The value of a string property, or the name of a user property. */ + MQTTLenString value; /**< The value of a user property. */ + }; + } value; +} MQTTProperty; + +/** + * MQTT version 5 property list + */ +typedef struct MQTTProperties +{ + int count; /**< number of property entries in the array */ + int max_count; /**< max number of properties that the currently allocated array can store */ + int length; /**< mbi: byte length of all properties */ + MQTTProperty *array; /**< array of properties */ +} MQTTProperties; + +#define MQTTProperties_initializer {0, 0, 0, NULL} + +/** + * Returns the length of the properties structure when serialized ready for network transmission. + * @param props an MQTT V5 property structure. + * @return the length in bytes of the properties when serialized. + */ +int MQTTProperties_len(MQTTProperties* props); + +/** + * Add a property pointer to the property array. There is no memory allocation. + * @param props The property list to add the property to. + * @param prop The property to add to the list. + * @return 0 on success, -1 on failure. + */ +LIBMQTT_API int MQTTProperties_add(MQTTProperties* props, const MQTTProperty* prop); + +/** + * Serialize the given property list to a character buffer, e.g. for writing to the network. + * @param pptr pointer to the buffer - move the pointer as we add data + * @param properties pointer to the property list, can be NULL + * @return whether the write succeeded or not: number of bytes written, or < 0 on failure. + */ +int MQTTProperties_write(char** pptr, const MQTTProperties* properties); + +/** + * Reads a property list from a character buffer into an array. + * @param properties pointer to the property list to be filled. Should be initalized but empty. + * @param pptr pointer to the character buffer. + * @param enddata pointer to the end of the character buffer so we don't read beyond. + * @return 1 if the properties were read successfully. + */ +int MQTTProperties_read(MQTTProperties* properties, char** pptr, char* enddata); + +/** + * Free all memory allocated to the property list, including any to individual properties. + * @param properties pointer to the property list. + */ +LIBMQTT_API void MQTTProperties_free(MQTTProperties* properties); + +/** + * Copy the contents of a property list, allocating additional memory if needed. + * @param props pointer to the property list. + * @return the duplicated property list. + */ +LIBMQTT_API MQTTProperties MQTTProperties_copy(const MQTTProperties* props); + +/** + * Checks if property list contains a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return 1 if found, 0 if not. + */ +LIBMQTT_API int MQTTProperties_hasProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the number of instances of a property id. Most properties can exist only once. + * User properties and subscription ids can exist more than once. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the number of times found. Can be 0. + */ +LIBMQTT_API int MQTTProperties_propertyCount(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property. The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValue(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property when it's not the only instance. + * The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValueAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +/** + * Returns a pointer to the property structure for a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns a pointer to the property structure for a specific property when it's not the only instance. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getPropertyAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +#endif /* MQTTPROPERTIES_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProtocol.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProtocol.h new file mode 100644 index 0000000..52bcd15 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProtocol.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - MQTT 3.1.1 updates + *******************************************************************************/ + +#if !defined(MQTTPROTOCOL_H) +#define MQTTPROTOCOL_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +typedef struct +{ + int socket; + Publications* p; +} pending_write; + + +typedef struct +{ + List publications; + unsigned int msgs_received; + unsigned int msgs_sent; + List pending_writes; /* for qos 0 writes not complete */ +} MQTTProtocol; + + +#include "MQTTProtocolOut.h" + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProtocolClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProtocolClient.h new file mode 100644 index 0000000..2d077af --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProtocolClient.h @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 updates + * Rong Xiang, Ian Craggs - C++ compatibility + * Ian Craggs - add debug definition of MQTTStrdup for when needed + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLCLIENT_H) +#define MQTTPROTOCOLCLIENT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Log.h" +#include "MQTTProtocol.h" +#include "Messages.h" +#include "MQTTProperties.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +int MQTTProtocol_startPublish(Clients* pubclient, Publish* publish, int qos, int retained, Messages** m); +Messages* MQTTProtocol_createMessage(Publish* publish, Messages** mm, int qos, int retained, int allocatePayload); +Publications* MQTTProtocol_storePublication(Publish* publish, int* len); +int messageIDCompare(void* a, void* b); +int MQTTProtocol_assignMsgId(Clients* client); +void MQTTProtocol_removePublication(Publications* p); +void Protocol_processPublication(Publish* publish, Clients* client, int allocatePayload); + +int MQTTProtocol_handlePublishes(void* pack, int sock); +int MQTTProtocol_handlePubacks(void* pack, int sock); +int MQTTProtocol_handlePubrecs(void* pack, int sock); +int MQTTProtocol_handlePubrels(void* pack, int sock); +int MQTTProtocol_handlePubcomps(void* pack, int sock); + +void MQTTProtocol_closeSession(Clients* c, int sendwill); +void MQTTProtocol_keepalive(START_TIME_TYPE); +void MQTTProtocol_retry(START_TIME_TYPE, int, int); +void MQTTProtocol_freeClient(Clients* client); +void MQTTProtocol_emptyMessageList(List* msgList); +void MQTTProtocol_freeMessageList(List* msgList); + +char* MQTTStrncpy(char *dest, const char* src, size_t num); +char* MQTTStrdup(const char* src); + +//#define MQTTStrdup(src) MQTTStrncpy(malloc(strlen(src)+1), src, strlen(src)+1) + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProtocolOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProtocolOut.h new file mode 100644 index 0000000..6a50155 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTProtocolOut.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - SNI support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLOUT_H) +#define MQTTPROTOCOLOUT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" +#include "Log.h" +#include "Messages.h" +#include "MQTTProtocol.h" +#include "MQTTProtocolClient.h" + +#define MQTT_DEFAULT_PORT 1883 +#define SECURE_MQTT_DEFAULT_PORT 8883 +#define WS_DEFAULT_PORT 80 + +size_t MQTTProtocol_addressPort(const char* uri, int* port, const char **topic, int default_port); +void MQTTProtocol_reconnect(const char* ip_address, Clients* client); +#if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#else +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#endif +int MQTTProtocol_handlePingresps(void* pack, int sock); +int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, int msgID, + MQTTSubscribe_options* opts, MQTTProperties* props); +int MQTTProtocol_handleSubacks(void* pack, int sock); +int MQTTProtocol_unsubscribe(Clients* client, List* topics, int msgID, MQTTProperties* props); +int MQTTProtocol_handleUnsubacks(void* pack, int sock); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTReasonCodes.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTReasonCodes.h new file mode 100644 index 0000000..2dc08ea --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTReasonCodes.h @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTREASONCODES_H) +#define MQTTREASONCODES_H + +#include "MQTTExportDeclarations.h" + +/** The MQTT V5 one byte reason code */ +enum MQTTReasonCodes { + MQTTREASONCODE_SUCCESS = 0, + MQTTREASONCODE_NORMAL_DISCONNECTION = 0, + MQTTREASONCODE_GRANTED_QOS_0 = 0, + MQTTREASONCODE_GRANTED_QOS_1 = 1, + MQTTREASONCODE_GRANTED_QOS_2 = 2, + MQTTREASONCODE_DISCONNECT_WITH_WILL_MESSAGE = 4, + MQTTREASONCODE_NO_MATCHING_SUBSCRIBERS = 16, + MQTTREASONCODE_NO_SUBSCRIPTION_FOUND = 17, + MQTTREASONCODE_CONTINUE_AUTHENTICATION = 24, + MQTTREASONCODE_RE_AUTHENTICATE = 25, + MQTTREASONCODE_UNSPECIFIED_ERROR = 128, + MQTTREASONCODE_MALFORMED_PACKET = 129, + MQTTREASONCODE_PROTOCOL_ERROR = 130, + MQTTREASONCODE_IMPLEMENTATION_SPECIFIC_ERROR = 131, + MQTTREASONCODE_UNSUPPORTED_PROTOCOL_VERSION = 132, + MQTTREASONCODE_CLIENT_IDENTIFIER_NOT_VALID = 133, + MQTTREASONCODE_BAD_USER_NAME_OR_PASSWORD = 134, + MQTTREASONCODE_NOT_AUTHORIZED = 135, + MQTTREASONCODE_SERVER_UNAVAILABLE = 136, + MQTTREASONCODE_SERVER_BUSY = 137, + MQTTREASONCODE_BANNED = 138, + MQTTREASONCODE_SERVER_SHUTTING_DOWN = 139, + MQTTREASONCODE_BAD_AUTHENTICATION_METHOD = 140, + MQTTREASONCODE_KEEP_ALIVE_TIMEOUT = 141, + MQTTREASONCODE_SESSION_TAKEN_OVER = 142, + MQTTREASONCODE_TOPIC_FILTER_INVALID = 143, + MQTTREASONCODE_TOPIC_NAME_INVALID = 144, + MQTTREASONCODE_PACKET_IDENTIFIER_IN_USE = 145, + MQTTREASONCODE_PACKET_IDENTIFIER_NOT_FOUND = 146, + MQTTREASONCODE_RECEIVE_MAXIMUM_EXCEEDED = 147, + MQTTREASONCODE_TOPIC_ALIAS_INVALID = 148, + MQTTREASONCODE_PACKET_TOO_LARGE = 149, + MQTTREASONCODE_MESSAGE_RATE_TOO_HIGH = 150, + MQTTREASONCODE_QUOTA_EXCEEDED = 151, + MQTTREASONCODE_ADMINISTRATIVE_ACTION = 152, + MQTTREASONCODE_PAYLOAD_FORMAT_INVALID = 153, + MQTTREASONCODE_RETAIN_NOT_SUPPORTED = 154, + MQTTREASONCODE_QOS_NOT_SUPPORTED = 155, + MQTTREASONCODE_USE_ANOTHER_SERVER = 156, + MQTTREASONCODE_SERVER_MOVED = 157, + MQTTREASONCODE_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158, + MQTTREASONCODE_CONNECTION_RATE_EXCEEDED = 159, + MQTTREASONCODE_MAXIMUM_CONNECT_TIME = 160, + MQTTREASONCODE_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161, + MQTTREASONCODE_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162 +}; + +/** + * Returns a printable string description of an MQTT V5 reason code. + * @param value an MQTT V5 reason code. + * @return the printable string description of the input reason code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTReasonCode_toString(enum MQTTReasonCodes value); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTSubscribeOpts.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTSubscribeOpts.h new file mode 100644 index 0000000..264e4d0 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTSubscribeOpts.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(SUBOPTS_H) +#define SUBOPTS_H + +/** The MQTT V5 subscribe options, apart from QoS which existed before V5. */ +typedef struct MQTTSubscribe_options +{ + /** The eyecatcher for this structure. Must be MQSO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0. + */ + int struct_version; + /** To not receive our own publications, set to 1. + * 0 is the original MQTT behaviour - all messages matching the subscription are received. + */ + unsigned char noLocal; + /** To keep the retain flag as on the original publish message, set to 1. + * If 0, defaults to the original MQTT behaviour where the retain flag is only set on + * publications sent by a broker if in response to a subscribe request. + */ + unsigned char retainAsPublished; + /** 0 - send retained messages at the time of the subscribe (original MQTT behaviour) + * 1 - send retained messages on subscribe only if the subscription is new + * 2 - do not send retained messages at all + */ + unsigned char retainHandling; +} MQTTSubscribe_options; + +#define MQTTSubscribe_options_initializer { {'M', 'Q', 'S', 'O'}, 0, 0, 0, 0 } + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTTime.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTTime.h new file mode 100644 index 0000000..8bd6860 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/MQTTTime.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + *******************************************************************************/ + +#if !defined(MQTTTIME_H) +#define MQTTTIME_H + +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#if WINVER >= _WIN32_WINNT_VISTA +#define START_TIME_TYPE ULONGLONG +#define START_TIME_ZERO 0 +#else +#define START_TIME_TYPE DWORD +#define START_TIME_ZERO 0 +#endif +#elif defined(AIX) +#define START_TIME_TYPE struct timespec +#define START_TIME_ZERO {0, 0} +#else +#include +#define START_TIME_TYPE struct timeval +#define START_TIME_ZERO {0, 0} +#endif + +#define ELAPSED_TIME_TYPE uint64_t +#define DIFF_TIME_TYPE int64_t + +void MQTTTime_sleep(ELAPSED_TIME_TYPE milliseconds); +START_TIME_TYPE MQTTTime_start_clock(void); +START_TIME_TYPE MQTTTime_now(void); +ELAPSED_TIME_TYPE MQTTTime_elapsed(START_TIME_TYPE milliseconds); +DIFF_TIME_TYPE MQTTTime_difftime(START_TIME_TYPE new, START_TIME_TYPE old); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Messages.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Messages.h new file mode 100644 index 0000000..58f5eae --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Messages.h @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MESSAGES_H) +#define MESSAGES_H + +#include "Log.h" + +const char* Messages_get(int, enum LOG_LEVELS); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/OsWrapper.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/OsWrapper.h new file mode 100644 index 0000000..96b629d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/OsWrapper.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016, 2017 logi.cals GmbH + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Gunter Raidl - timer support for VxWorks + * Rainer Poisel - reusability + *******************************************************************************/ + +#if !defined(OSWRAPPER_H) +#define OSWRAPPER_H + +#if defined(_WRS_KERNEL) +#include + +#define lstat stat + +typedef unsigned long useconds_t; +void usleep(useconds_t useconds); + +#define timersub(a, b, result) \ + do \ + { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) \ + { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000L; \ + } \ + } while (0) +#endif /* defined(_WRS_KERNEL) */ + +#endif /* OSWRAPPER_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/SHA1.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/SHA1.h new file mode 100644 index 0000000..3ae2f0a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/SHA1.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2018, 2019 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(SHA1_H) +#define SHA1_H + +#if defined(OPENSSL) +#include + +/** SHA-1 Digest Length */ +#define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH + +#else /* if defined(OPENSSL) */ + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +typedef struct SHA_CTX_S +{ + HCRYPTPROV hProv; + HCRYPTHASH hHash; +} SHA_CTX; +#else /* if defined(_WIN32) || defined(_WIN64) */ + +#include +typedef struct SHA_CTX_S { + uint32_t h[5]; + union { + uint32_t w[16]; + uint8_t buffer[64]; + }; + unsigned int size; + unsigned int total; +} SHA_CTX; +#endif /* else if defined(_WIN32) || defined(_WIN64) */ + +#include + +/** SHA-1 Digest Length (number of bytes in SHA1) */ +#define SHA1_DIGEST_LENGTH (160/8) + +/** + * Initializes the SHA1 hashing algorithm + * + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Update + * @see SHA1_Final + */ +int SHA1_Init(SHA_CTX *ctx); + +/** + * Updates a block to the SHA1 hash + * + * @param[in,out] ctx hashing context structure + * @param[in] data block of data to hash + * @param[in] len length of block to hash + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Update(SHA_CTX *ctx, const void *data, size_t len); + +/** + * Produce final SHA1 hash + * + * @param[out] md SHA1 hash produced (must be atleast + * @p SHA1_DIGEST_LENGTH in length) + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Final(unsigned char *md, SHA_CTX *ctx); + +#endif /* if defined(OPENSSL) */ +#endif /* SHA1_H */ + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/SSLSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/SSLSocket.h new file mode 100644 index 0000000..86273c8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/SSLSocket.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs, Allan Stockdill-Mander - initial implementation + * Ian Craggs - SNI support + * Ian Craggs - post connect checks and CApath + *******************************************************************************/ +#if !defined(SSLSOCKET_H) +#define SSLSOCKET_H + +#if defined(_WIN32) || defined(_WIN64) + #define ssl_mutex_type HANDLE +#else + #include + #include + #define ssl_mutex_type pthread_mutex_t +#endif + +#include +#include "SocketBuffer.h" +#include "Clients.h" + +#define URI_SSL "ssl://" + +/** if we should handle openssl initialization (bool_value == 1) or depend on it to be initalized externally (bool_value == 0) */ +void SSLSocket_handleOpensslInit(int bool_value); + +int SSLSocket_initialize(void); +void SSLSocket_terminate(void); +int SSLSocket_setSocketForSSL(networkHandles* net, MQTTClient_SSLOptions* opts, const char* hostname, size_t hostname_len); + +int SSLSocket_getch(SSL* ssl, int socket, char* c); +char *SSLSocket_getdata(SSL* ssl, int socket, size_t bytes, size_t* actual_len, int* rc); + +int SSLSocket_close(networkHandles* net); +int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +int SSLSocket_connect(SSL* ssl, int sock, const char* hostname, int verify, int (*cb)(const char *str, size_t len, void *u), void* u); + +int SSLSocket_getPendingRead(void); +int SSLSocket_continueWrite(pending_writes* pw); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Socket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Socket.h new file mode 100644 index 0000000..39a8158 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Socket.h @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + * Ian Craggs - async client updates + *******************************************************************************/ + +#if !defined(SOCKET_H) +#define SOCKET_H + +#include +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#include +#define MAXHOSTNAMELEN 256 +#if !defined(SSLSOCKET_H) +#undef EAGAIN +#define EAGAIN WSAEWOULDBLOCK +#undef EINTR +#define EINTR WSAEINTR +#undef EINPROGRESS +#define EINPROGRESS WSAEINPROGRESS +#undef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#undef ENOTCONN +#define ENOTCONN WSAENOTCONN +#undef ECONNRESET +#define ECONNRESET WSAECONNRESET +#undef ETIMEDOUT +#define ETIMEDOUT WAIT_TIMEOUT +#endif +#define ioctl ioctlsocket +#define socklen_t int +#else +#define INVALID_SOCKET SOCKET_ERROR +#include +#if !defined(_WRS_KERNEL) +#include +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define ULONG size_t +#endif + +#include "mutex_type.h" /* Needed for mutex_type */ + +/** socket operation completed successfully */ +#define TCPSOCKET_COMPLETE 0 +#if !defined(SOCKET_ERROR) + /** error in socket operation */ + #define SOCKET_ERROR -1 +#endif +/** must be the same as SOCKETBUFFER_INTERRUPTED */ +#define TCPSOCKET_INTERRUPTED -22 +#define SSL_FATAL -3 + +#if !defined(INET6_ADDRSTRLEN) +#define INET6_ADDRSTRLEN 46 /** only needed for gcc/cygwin on windows */ +#endif + + +#if !defined(max) +#define max(A,B) ( (A) > (B) ? (A):(B)) +#endif + +#include "LinkedList.h" + +/* + * Network write buffers for an MQTT packet + */ +typedef struct +{ + int count; /**> number of buffers/buflens/frees */ + char** buffers; /**> array of byte buffers */ + size_t* buflens; /**> array of lengths of buffers */ + int* frees; /**> array of flags indicating whether each buffer needs to be freed */ + uint8_t mask[4]; /**> websocket mask used to mask the buffer data, if any */ +} PacketBuffers; + + +/** + * Structure to hold all socket data for the module + */ +typedef struct +{ + fd_set rset, /**< socket read set (see select doc) */ + rset_saved; /**< saved socket read set */ + int maxfdp1; /**< max descriptor used +1 (again see select doc) */ + List* clientsds; /**< list of client socket descriptors */ + ListElement* cur_clientsds; /**< current client socket descriptor (iterator) */ + List* connect_pending; /**< list of sockets for which a connect is pending */ + List* write_pending; /**< list of sockets for which a write is pending */ + fd_set pending_wset; /**< socket pending write set for select */ +} Sockets; + + +void Socket_outInitialize(void); +void Socket_outTerminate(void); +int Socket_getReadySocket(int more_work, struct timeval *tp, mutex_type mutex, int* rc); +int Socket_getch(int socket, char* c); +char *Socket_getdata(int socket, size_t bytes, size_t* actual_len, int* rc); +int Socket_putdatas(int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +void Socket_close(int socket); +#if defined(__GNUC__) && defined(__linux__) +/* able to use GNU's getaddrinfo_a to make timeouts possible */ +int Socket_new(const char* addr, size_t addr_len, int port, int* socket, long timeout); +#else +int Socket_new(const char* addr, size_t addr_len, int port, int* socket); +#endif + +int Socket_noPendingWrites(int socket); +char* Socket_getpeer(int sock); + +void Socket_addPendingWrite(int socket); +void Socket_clearPendingWrite(int socket); + +typedef void Socket_writeComplete(int socket, int rc); +void Socket_setWriteCompleteCallback(Socket_writeComplete*); + +#endif /* SOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/SocketBuffer.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/SocketBuffer.h new file mode 100644 index 0000000..0fc7d6e --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/SocketBuffer.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + *******************************************************************************/ + +#if !defined(SOCKETBUFFER_H) +#define SOCKETBUFFER_H + +#if defined(_WIN32) || defined(_WIN64) +#include +#else +#include +#endif + +#if defined(OPENSSL) +#include +#endif + +#if defined(_WIN32) || defined(_WIN64) + typedef WSABUF iobuf; +#else + typedef struct iovec iobuf; +#endif + +typedef struct +{ + int socket; + unsigned int index; + size_t headerlen; + char fixed_header[5]; /**< header plus up to 4 length bytes */ + size_t buflen, /**< total length of the buffer */ + datalen; /**< current length of data in buf */ + char* buf; +} socket_queue; + +typedef struct +{ + int socket, count; + size_t total; +#if defined(OPENSSL) + SSL* ssl; +#endif + size_t bytes; + iobuf iovecs[5]; + int frees[5]; +} pending_writes; + +#define SOCKETBUFFER_COMPLETE 0 +#if !defined(SOCKET_ERROR) + #define SOCKET_ERROR -1 +#endif +#define SOCKETBUFFER_INTERRUPTED -22 /* must be the same value as TCPSOCKET_INTERRUPTED */ + +int SocketBuffer_initialize(void); +void SocketBuffer_terminate(void); +void SocketBuffer_cleanup(int socket); +char* SocketBuffer_getQueuedData(int socket, size_t bytes, size_t* actual_len); +int SocketBuffer_getQueuedChar(int socket, char* c); +void SocketBuffer_interrupted(int socket, size_t actual_len); +char* SocketBuffer_complete(int socket); +void SocketBuffer_queueChar(int socket, char c); + +#if defined(OPENSSL) +int SocketBuffer_pendingWrite(int socket, SSL* ssl, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#else +int SocketBuffer_pendingWrite(int socket, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#endif +pending_writes* SocketBuffer_getWrite(int socket); +int SocketBuffer_writeComplete(int socket); +pending_writes* SocketBuffer_updateWrite(int socket, char* topic, char* payload); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/StackTrace.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/StackTrace.h new file mode 100644 index 0000000..c4f0d43 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/StackTrace.h @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#ifndef STACKTRACE_H_ +#define STACKTRACE_H_ + +#if defined(HIGH_PERFORMANCE) +#define NOSTACKTRACE 1 +#endif + +#include +#include "Log.h" +#include "Thread.h" + +#if defined(NOSTACKTRACE) +#define FUNC_ENTRY +#define FUNC_ENTRY_NOLOG +#define FUNC_ENTRY_MED +#define FUNC_ENTRY_MAX +#define FUNC_EXIT +#define FUNC_EXIT_NOLOG +#define FUNC_EXIT_MED +#define FUNC_EXIT_MAX +#define FUNC_EXIT_RC(x) +#define FUNC_EXIT_MED_RC(x) +#define FUNC_EXIT_MAX_RC(x) +#else +#if defined(_WIN32) || defined(_WIN64) +#define inline __inline +#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM) +#else +#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM) +#endif +#endif + +void StackTrace_entry(const char* name, int line, enum LOG_LEVELS trace); +void StackTrace_exit(const char* name, int line, void* return_value, enum LOG_LEVELS trace); + +void StackTrace_printStack(FILE* dest); +char* StackTrace_get(thread_id_type, char* buf, int bufsize); + +#endif /* STACKTRACE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Thread.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Thread.h new file mode 100644 index 0000000..29903f5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Thread.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + * Ian Craggs, Allan Stockdill-Mander - async client updates + * Ian Craggs - fix for bug #420851 + * Ian Craggs - change MacOS semaphore implementation + *******************************************************************************/ + +#if !defined(THREAD_H) +#define THREAD_H + +#include "MQTTExportDeclarations.h" + +#include "MQTTClient.h" + +#include "mutex_type.h" /* Needed for mutex_type */ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define thread_type HANDLE + #define thread_id_type DWORD + #define thread_return_type DWORD + #define thread_fn LPTHREAD_START_ROUTINE + #define cond_type HANDLE + #define sem_type HANDLE + #undef ETIMEDOUT + #define ETIMEDOUT WSAETIMEDOUT +#else + #include + + #define thread_type pthread_t + #define thread_id_type pthread_t + #define thread_return_type void* + typedef thread_return_type (*thread_fn)(void*); + typedef struct { pthread_cond_t cond; pthread_mutex_t mutex; } cond_type_struct; + typedef cond_type_struct *cond_type; + #if defined(OSX) + #include + typedef dispatch_semaphore_t sem_type; + #else + #include + typedef sem_t *sem_type; + #endif + + cond_type Thread_create_cond(int*); + int Thread_signal_cond(cond_type); + int Thread_wait_cond(cond_type condvar, int timeout); + int Thread_destroy_cond(cond_type); +#endif + +LIBMQTT_API thread_type Thread_start(thread_fn, void*); + +LIBMQTT_API mutex_type Thread_create_mutex(int*); +LIBMQTT_API int Thread_lock_mutex(mutex_type); +LIBMQTT_API int Thread_unlock_mutex(mutex_type); +int Thread_destroy_mutex(mutex_type); + +LIBMQTT_API thread_id_type Thread_getid(); + +sem_type Thread_create_sem(int*); +int Thread_wait_sem(sem_type sem, int timeout); +int Thread_check_sem(sem_type sem); +int Thread_post_sem(sem_type sem); +int Thread_destroy_sem(sem_type sem); + + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Tree.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Tree.h new file mode 100644 index 0000000..dfd70ab --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/Tree.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + + +#if !defined(TREE_H) +#define TREE_H + +#include /* for size_t definition */ + +/*BE +defm defTree(T) // macro to define a tree + +def T concat Node +{ + n32 ptr T concat Node "parent" + n32 ptr T concat Node "left" + n32 ptr T concat Node "right" + n32 ptr T id2str(T) + n32 suppress "size" +} + + +def T concat Tree +{ + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + n32 dec "count" + n32 dec suppress "size" +} + +endm + +defTree(INT) +defTree(STRING) +defTree(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct NodeStruct +{ + struct NodeStruct *parent, /**< pointer to parent tree node, in case we need it */ + *child[2]; /**< pointers to child tree nodes 0 = left, 1 = right */ + void* content; /**< pointer to element content */ + size_t size; /**< size of content */ + unsigned int red : 1; +} Node; + + +/** + * Structure to hold all data for one tree + */ +typedef struct +{ + struct + { + Node *root; /**< root node pointer */ + int (*compare)(void*, void*, int); /**< comparison function */ + } index[2]; + int indexes, /**< no of indexes into tree */ + count; /**< no of items */ + size_t size; /**< heap storage used */ + unsigned int heap_tracking : 1; /**< switch on heap tracking for this tree? */ + unsigned int allow_duplicates : 1; /**< switch to allow duplicate entries */ +} Tree; + + +Tree* TreeInitialize(int(*compare)(void*, void*, int)); +void TreeInitializeNoMalloc(Tree* aTree, int(*compare)(void*, void*, int)); +void TreeAddIndex(Tree* aTree, int(*compare)(void*, void*, int)); + +void* TreeAdd(Tree* aTree, void* content, size_t size); + +void* TreeRemove(Tree* aTree, void* content); + +void* TreeRemoveKey(Tree* aTree, void* key); +void* TreeRemoveKeyIndex(Tree* aTree, void* key, int index); + +void* TreeRemoveNodeIndex(Tree* aTree, Node* aNode, int index); + +void TreeFree(Tree* aTree); + +Node* TreeFind(Tree* aTree, void* key); +Node* TreeFindIndex(Tree* aTree, void* key, int index); + +Node* TreeNextElement(Tree* aTree, Node* curnode); + +int TreeIntCompare(void* a, void* b, int); +int TreePtrCompare(void* a, void* b, int); +int TreeStringCompare(void* a, void* b, int); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/VersionInfo.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/VersionInfo.h new file mode 100644 index 0000000..b3b3e78 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/VersionInfo.h @@ -0,0 +1,7 @@ +#ifndef VERSIONINFO_H +#define VERSIONINFO_H + +#define BUILD_TIMESTAMP "2021-02-11 12:10" +#define CLIENT_VERSION "1.3.8" + +#endif /* VERSIONINFO_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/WebSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/WebSocket.h new file mode 100644 index 0000000..e9f5765 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/WebSocket.h @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2018, 2020 Wind River Systems, Inc. and others. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(WEBSOCKET_H) +#define WEBSOCKET_H + +#include "MQTTPacket.h" + +/** + * WebSocket op codes + * @{ + */ +#define WebSocket_OP_CONTINUE 0x0 /* 0000 - continue frame */ +#define WebSocket_OP_TEXT 0x1 /* 0001 - text frame */ +#define WebSocket_OP_BINARY 0x2 /* 0010 - binary frame */ +#define WebSocket_OP_CLOSE 0x8 /* 1000 - close frame */ +#define WebSocket_OP_PING 0x9 /* 1001 - ping frame */ +#define WebSocket_OP_PONG 0xA /* 1010 - pong frame */ +/** @} */ + +/** + * Various close status codes + * @{ + */ +#define WebSocket_CLOSE_NORMAL 1000 +#define WebSocket_CLOSE_GOING_AWAY 1001 +#define WebSocket_CLOSE_PROTOCOL_ERROR 1002 +#define WebSocket_CLOSE_UNKNOWN_DATA 1003 +#define WebSocket_CLOSE_RESERVED 1004 +#define WebSocket_CLOSE_NO_STATUS_CODE 1005 /* reserved: not to be used */ +#define WebSocket_CLOSE_ABNORMAL 1006 /* reserved: not to be used */ +#define WebSocket_CLOSE_BAD_DATA 1007 +#define WebSocket_CLOSE_POLICY 1008 +#define WebSocket_CLOSE_MSG_TOO_BIG 1009 +#define WebSocket_CLOSE_NO_EXTENSION 1010 +#define WebScoket_CLOSE_UNEXPECTED 1011 +#define WebSocket_CLOSE_TLS_FAIL 1015 /* reserved: not be used */ +/** @} */ + +/* closes a websocket connection */ +void WebSocket_close(networkHandles *net, int status_code, const char *reason); + +/* sends upgrade request */ +int WebSocket_connect(networkHandles *net, const char *uri); + +/* obtain data from network socket */ +int WebSocket_getch(networkHandles *net, char* c); +char *WebSocket_getdata(networkHandles *net, size_t bytes, size_t* actual_len); +size_t WebSocket_framePos(); +void WebSocket_framePosSeekTo(size_t); + +/* send data out, in websocket format only if required */ +int WebSocket_putdatas(networkHandles* net, char** buf0, size_t* buf0len, PacketBuffers* bufs); + +/* releases any resources used by the websocket system */ +void WebSocket_terminate(void); + +/* handles websocket upgrade request */ +int WebSocket_upgrade(networkHandles *net); + +/* Notify the IP address and port of the endpoint to proxy, and wait connection to endpoint */ +int WebSocket_proxy_connect( networkHandles *net, int ssl, const char *hostname); + +#endif /* WEBSOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/mutex_type.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/mutex_type.h new file mode 100644 index 0000000..1e4b9e5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/mutex_type.h @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + *******************************************************************************/ +#if !defined(_MUTEX_TYPE_H_) +#define _MUTEX_TYPE_H_ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define mutex_type HANDLE +#else + #include + #define mutex_type pthread_mutex_t* +#endif + +#endif /* _MUTEX_TYPE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/utf-8.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/utf-8.h new file mode 100644 index 0000000..a7a4270 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/include/utf-8.h @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(UTF8_H) +#define UTF8_H + +int UTF8_validate(int len, const char *data); +int UTF8_validateString(const char* string); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libAR.a new file mode 100644 index 0000000..41d916b Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libOpenSSL_s.a new file mode 100644 index 0000000..edd3f85 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libPahoMQTT_s.a new file mode 100644 index 0000000..3d86947 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libar_posix_s.a new file mode 100644 index 0000000..01273df Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libarsystem.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libarsystem.a new file mode 100644 index 0000000..1d21e27 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/libarsystem.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/librtk_lib.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/librtk_lib.a new file mode 100644 index 0000000..e364103 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.26.0/SG4/librtk_lib.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/Binary.lby b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/Binary.lby new file mode 100644 index 0000000..b07c8f2 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/Binary.lby @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libAR.a new file mode 100644 index 0000000..235f5d6 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libOpenSSL_s.a new file mode 100644 index 0000000..2e7af3e Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libPahoMQTT_s.a new file mode 100644 index 0000000..c2cddac Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libar_posix_s.a new file mode 100644 index 0000000..cc787ef Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libarsystem.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libarsystem.a new file mode 100644 index 0000000..8aecb24 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/libarsystem.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/librtk_lib.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/librtk_lib.a new file mode 100644 index 0000000..6cd6be3 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/Arm/librtk_lib.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Base64.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Base64.h new file mode 100644 index 0000000..7022ce8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Base64.h @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2018 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(BASE64_H) +#define BASE64_H + +/** type for size of a buffer, it saves passing around @p size_t (unsigned long long or unsigned long int) */ +typedef unsigned int b64_size_t; +/** type for raw base64 data */ +typedef unsigned char b64_data_t; + +/** + * Decodes base64 data + * + * @param[out] out decoded data + * @param[in] out_len length of output buffer + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the amount of data decoded + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_decode( b64_data_t *out, b64_size_t out_len, + const char *in, b64_size_t in_len ); + +/** + * Size of buffer required to decode base64 data + * + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the decoded string would require + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_decodeLength( const char *in, b64_size_t in_len ); + +/** + * Encodes base64 data + * + * @param[out] out encode base64 string + * @param[in] out_len length of output buffer + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the amount of data encoded + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_encode( char *out, b64_size_t out_len, + const b64_data_t *in, b64_size_t in_len ); + +/** + * Size of buffer required to encode base64 data + * + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the encoded string would require + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_encodeLength( const b64_data_t *in, b64_size_t in_len ); + +#endif /* BASE64_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Clients.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Clients.h new file mode 100644 index 0000000..a3ddb1f --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Clients.h @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - add SSL support + * Ian Craggs - fix for bug 413429 - connectionLost not called + * Ian Craggs - change will payload to binary + * Ian Craggs - password to binary + * Ian Craggs - MQTT 5 support + *******************************************************************************/ + +#if !defined(CLIENTS_H) +#define CLIENTS_H + +#include +#include "MQTTTime.h" +#if defined(OPENSSL) +#if defined(_WIN32) || defined(_WIN64) +#include +#endif +#include +#endif +#include "MQTTClient.h" +#include "LinkedList.h" +#include "MQTTClientPersistence.h" + +/** + * Stored publication data to minimize copying + */ +typedef struct +{ + char *topic; + int topiclen; + char* payload; + int payloadlen; + int refcount; + uint8_t mask[4]; +} Publications; + +/** + * Client publication message data + */ +typedef struct +{ + int qos; + int retain; + int msgid; + int MQTTVersion; + MQTTProperties properties; + Publications *publish; + START_TIME_TYPE lastTouch; /**> used for retry and expiry */ + char nextMessageType; /**> PUBREC, PUBREL, PUBCOMP */ + int len; /**> length of the whole structure+data */ +} Messages; + +/** + * Client will message data + */ +typedef struct +{ + char *topic; + int payloadlen; + void *payload; + int retained; + int qos; +} willMessages; + +typedef struct +{ + int socket; + START_TIME_TYPE lastSent; + START_TIME_TYPE lastReceived; + START_TIME_TYPE lastPing; +#if defined(OPENSSL) + SSL* ssl; + SSL_CTX* ctx; + char *https_proxy; + char *https_proxy_auth; +#endif + char *http_proxy; + char *http_proxy_auth; + int websocket; /**< socket has been upgraded to use web sockets */ + char *websocket_key; + const MQTTClient_nameValue* httpHeaders; +} networkHandles; + + +/* connection states */ +/** no connection in progress, see connected value */ +#define NOT_IN_PROGRESS 0x0 +/** TCP connection in progress */ +#define TCP_IN_PROGRESS 0x1 +/** SSL connection in progress */ +#define SSL_IN_PROGRESS 0x2 +/** Websocket connection in progress */ +#define WEBSOCKET_IN_PROGRESS 0x3 +/** TCP completed, waiting for MQTT ACK */ +#define WAIT_FOR_CONNACK 0x4 +/** Proxy connection in progress */ +#define PROXY_CONNECT_IN_PROGRESS 0x5 +/** Disconnecting */ +#define DISCONNECTING -2 + +/** + * Data related to one client + */ +typedef struct +{ + char* clientID; /**< the string id of the client */ + const char* username; /**< MQTT v3.1 user name */ + int passwordlen; /**< MQTT password length */ + const void* password; /**< MQTT v3.1 binary password */ + unsigned int cleansession : 1; /**< MQTT V3 clean session flag */ + unsigned int cleanstart : 1; /**< MQTT V5 clean start flag */ + unsigned int connected : 1; /**< whether it is currently connected */ + unsigned int good : 1; /**< if we have an error on the socket we turn this off */ + unsigned int ping_outstanding : 1; + signed int connect_state : 4; + networkHandles net; /**< network info for this client */ + int msgID; /**< the MQTT message id */ + int keepAliveInterval; /**< the MQTT keep alive interval */ + int retryInterval; + int maxInflightMessages; /**< the max number of inflight outbound messages we allow */ + willMessages* will; /**< the MQTT will message, if any */ + List* inboundMsgs; /**< inbound in flight messages */ + List* outboundMsgs; /**< outbound in flight messages */ + List* messageQueue; /**< inbound complete but undelivered messages */ + unsigned int qentry_seqno; + void* phandle; /**< the persistence handle */ + MQTTClient_persistence* persistence; /**< a persistence implementation */ + MQTTPersistence_beforeWrite* beforeWrite; /**< persistence write callback */ + MQTTPersistence_afterRead* afterRead; /**< persistence read callback */ + void* beforeWrite_context; /**< context to be used with the persistence beforeWrite callbacks */ + void* afterRead_context; /**< context to be used with the persistence afterRead callback */ + void* context; /**< calling context - used when calling disconnect_internal */ + int MQTTVersion; /**< the version of MQTT being used, 3, 4 or 5 */ + int sessionExpiry; /**< MQTT 5 session expiry */ + char* httpProxy; /**< HTTP proxy for websockets */ + char* httpsProxy; /**< HTTPS proxy for websockets */ +#if defined(OPENSSL) + MQTTClient_SSLOptions *sslopts; /**< the SSL/TLS connect options */ + SSL_SESSION* session; /**< SSL session pointer for fast handhake */ +#endif +} Clients; + +int clientIDCompare(void* a, void* b); +int clientSocketCompare(void* a, void* b); + +/** + * Configuration data related to all clients + */ +typedef struct +{ + const char* version; + List* clients; +} ClientStates; + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Heap.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Heap.h new file mode 100644 index 0000000..f89a760 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Heap.h @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - use tree data structure instead of list + *******************************************************************************/ + + +#if !defined(HEAP_H) +#define HEAP_H + +#if defined(HIGH_PERFORMANCE) +#define NO_HEAP_TRACKING 1 +#endif + +#define PAHO_MEMORY_ERROR -99 + +#include "MQTTExportDeclarations.h" + +#include +#include + +#if !defined(NO_HEAP_TRACKING) + +#if !defined(TREE_C) +/** + * redefines malloc to use "mymalloc" so that heap allocation can be tracked + * @param x the size of the item to be allocated + * @return the pointer to the item allocated, or NULL + */ +#define malloc(x) mymalloc(__FILE__, __LINE__, x) + +/** + * redefines realloc to use "myrealloc" so that heap allocation can be tracked + * @param a the heap item to be reallocated + * @param b the new size of the item + * @return the new pointer to the heap item + */ +#define realloc(a, b) myrealloc(__FILE__, __LINE__, a, b) + +/** + * redefines free to use "myfree" so that heap allocation can be tracked + * @param x the size of the item to be freed + */ +#define free(x) myfree(__FILE__, __LINE__, x) + +#endif + +/** + * Information about the state of the heap. + */ +typedef struct +{ + size_t current_size; /**< current size of the heap in bytes */ + size_t max_size; /**< max size the heap has reached in bytes */ +} heap_info; + +#if defined(__cplusplus) + extern "C" { +#endif + +void* mymalloc(char*, int, size_t size); +void* myrealloc(char*, int, void* p, size_t size); +void myfree(char*, int, void* p); + +void Heap_scan(FILE* file); +int Heap_initialize(void); +void Heap_terminate(void); +LIBMQTT_API heap_info* Heap_get_info(void); +int HeapDump(FILE* file); +int HeapDumpString(FILE* file, char* str); +void* Heap_findItem(void* p); +void Heap_unlink(char* file, int line, void* p); +#ifdef __cplusplus + } +#endif + +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/LinkedList.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/LinkedList.h new file mode 100644 index 0000000..e390012 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/LinkedList.h @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + * Ian Craggs - change size types from int to size_t + *******************************************************************************/ + +#if !defined(LINKEDLIST_H) +#define LINKEDLIST_H + +#include /* for size_t definition */ + +/*BE +defm defList(T) + +def T concat Item +{ + at 4 + n32 ptr T concat Item suppress "next" + at 0 + n32 ptr T concat Item suppress "prev" + at 8 + n32 ptr T id2str(T) +} + +def T concat List +{ + n32 ptr T concat Item suppress "first" + n32 ptr T concat Item suppress "last" + n32 ptr T concat Item suppress "current" + n32 dec "count" + n32 suppress "size" +} +endm + +defList(INT) +defList(STRING) +defList(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct ListElementStruct +{ + struct ListElementStruct *prev, /**< pointer to previous list element */ + *next; /**< pointer to next list element */ + void* content; /**< pointer to element content */ +} ListElement; + + +/** + * Structure to hold all data for one list + */ +typedef struct +{ + ListElement *first, /**< first element in the list */ + *last, /**< last element in the list */ + *current; /**< current element in the list, for iteration */ + int count; /**< no of items */ + size_t size; /**< heap storage used */ +} List; + +void ListZero(List*); +List* ListInitialize(void); + +ListElement* ListAppend(List* aList, void* content, size_t size); +void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, size_t size); +ListElement* ListInsert(List* aList, void* content, size_t size, ListElement* index); + +int ListRemove(List* aList, void* content); +int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*)); +void* ListDetachHead(List* aList); +int ListRemoveHead(List* aList); +void* ListPopTail(List* aList); + +int ListDetach(List* aList, void* content); +int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*)); + +void ListFree(List* aList); +void ListEmpty(List* aList); +void ListFreeNoContent(List* aList); + +ListElement* ListNextElement(List* aList, ListElement** pos); +ListElement* ListPrevElement(List* aList, ListElement** pos); + +ListElement* ListFind(List* aList, void* content); +ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*)); + +int intcompare(void* a, void* b); +int stringcompare(void* a, void* b); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Log.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Log.h new file mode 100644 index 0000000..102e31d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Log.h @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + *******************************************************************************/ + +#if !defined(LOG_H) +#define LOG_H + +/*BE +map LOG_LEVELS +{ + "TRACE_MAXIMUM" 1 + "TRACE_MEDIUM" 2 + "TRACE_MINIMUM" 3 + "TRACE_PROTOCOL" 4 + + "ERROR" 5 + "SEVERE" 6 + "FATAL" 7 +} +BE*/ + +enum LOG_LEVELS { + INVALID_LEVEL = -1, + TRACE_MAXIMUM = 1, + TRACE_MEDIUM, + TRACE_MINIMUM, + TRACE_PROTOCOL, + LOG_ERROR, + LOG_SEVERE, + LOG_FATAL, +}; + + +/*BE +def trace_settings_type +{ + n32 map LOG_LEVELS "trace_level" + n32 dec "max_trace_entries" + n32 dec "trace_output_level" +} +BE*/ +typedef struct +{ + enum LOG_LEVELS trace_level; /**< trace level */ + int max_trace_entries; /**< max no of entries in the trace buffer */ + enum LOG_LEVELS trace_output_level; /**< trace level to output to destination */ +} trace_settings_type; + +extern trace_settings_type trace_settings; + +#define LOG_PROTOCOL TRACE_PROTOCOL +#define TRACE_MAX TRACE_MAXIMUM +#define TRACE_MIN TRACE_MINIMUM +#define TRACE_MED TRACE_MEDIUM + +typedef struct +{ + const char* name; + const char* value; +} Log_nameValue; + +int Log_initialize(Log_nameValue*); +void Log_terminate(void); + +void Log(enum LOG_LEVELS, int, const char *, ...); +void Log_stackTrace(enum LOG_LEVELS, int, int, int, const char*, int, int*); + +typedef void Log_traceCallback(enum LOG_LEVELS level, const char *message); +void Log_setTraceCallback(Log_traceCallback* callback); +void Log_setTraceLevel(enum LOG_LEVELS level); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTAsync.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTAsync.h new file mode 100644 index 0000000..f728ba5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTAsync.h @@ -0,0 +1,2345 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation + * Ian Craggs, Allan Stockdill-Mander - SSL connections + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - fix for bug 444103 - success/failure callbacks not invoked + * Ian Craggs - automatic reconnect and offline buffering (send while disconnected) + * Ian Craggs - binary will message + * Ian Craggs - binary password + * Ian Craggs - remove const on eyecatchers #168 + * Ian Craggs - MQTT 5.0 + *******************************************************************************/ + +/********************************************************************/ + +/** + * @cond MQTTAsync_main + * @mainpage Asynchronous MQTT client library for C + * + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An Asynchronous MQTT client library for C. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the Asynchronous MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions
  • + *
  • Connect the client to an MQTT server
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref publish
  • + *
  • @ref subscribe
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
  • @ref auto_reconnect
  • + *
  • @ref offline_publish
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTASYNC_H) +#define MQTTASYNC_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTASYNC_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTASYNC_FAILURE -1 + +/* error code -2 is MQTTAsync_PERSISTENCE_ERROR */ + +#define MQTTASYNC_PERSISTENCE_ERROR -2 + +/** + * Return code: The client is disconnected. + */ +#define MQTTASYNC_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTASYNC_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTASYNC_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTASYNC_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTASYNC_BAD_STRUCTURE -8 +/** + * Return code: A qos parameter is not 0, 1 or 2 + */ +#define MQTTASYNC_BAD_QOS -9 +/** + * Return code: All 65535 MQTT msgids are being used + */ +#define MQTTASYNC_NO_MORE_MSGIDS -10 +/** + * Return code: the request is being discarded when not complete + */ +#define MQTTASYNC_OPERATION_INCOMPLETE -11 +/** + * Return code: no more messages can be buffered + */ +#define MQTTASYNC_MAX_BUFFERED_MESSAGES -12 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTASYNC_SSL_NOT_SUPPORTED -13 + /** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if the TLS version of the library + * is linked with. + */ +#define MQTTASYNC_BAD_PROTOCOL -14 + /** + * Return code: don't use options for another version of MQTT + */ + #define MQTTASYNC_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the client's version of MQTT + */ + #define MQTTASYNC_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic + */ + #define MQTTASYNC_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 +/** + * MQTT version to connect with: 5 + */ +#define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTAsync_init_options; + +#define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt (0) + */ +LIBMQTT_API void MQTTAsync_global_init(MQTTAsync_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTAsync_create(). + */ +typedef void* MQTTAsync; +/** + * A value representing an MQTT message. A token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTAsync_publish(), + * MQTTAsync_publishMessage(), + * MQTTAsync_deliveryComplete(), and + * MQTTAsync_getPendingTokens()). + */ +typedef int MQTTAsync_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTAsync_publishMessage(), + * MQTTAsync_publish(), MQTTAsync_receive(), MQTTAsync_freeMessage() + * and MQTTAsync_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. This is an output parameter only. + */ + int dup; + /** The message identifier is reserved for internal use by the + * MQTT client and server. It is an output parameter only - writing + * to it will serve no purpose. It contains the MQTT message id of + * an incoming publish message. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTAsync_message; + +#define MQTTAsync_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTAsync_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTAsync_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTAsync_freeMessage must be called. + * To free the topic name storage, ::MQTTAsync_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTAsync_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTAsync_messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages to the server. The function is + * registered with the client library by passing it as an argument to MQTTAsync_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTAsync_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param token The ::MQTTAsync_token associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the tokens returned from calls to + * MQTTAsync_send() and MQTTAsync_sendMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTAsync_deliveryComplete(void* context, MQTTAsync_token token); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTAsync_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connectionLost(void* context, char* cause); + + +/** + * This is a callback function, which will be called when the client + * library successfully connects. This is superfluous when the connection + * is made in response to a MQTTAsync_connect call, because the onSuccess + * callback can be used. It is intended for use when automatic reconnect + * is enabled, so that when a reconnection attempt succeeds in the background, + * the application is notified and can take any required actions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connected(void* context, char* cause); + +/** + * This is a callback function, which will be called when the client + * library receives a disconnect packet. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param properties the properties in the disconnect packet. + * @param properties the reason code from the disconnect packet + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTAsync_disconnected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDisconnected(MQTTAsync handle, void* context, MQTTAsync_disconnected* co); + +/** The connect options that can be updated before an automatic reconnect. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQCD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name parameter. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + const char* username; + /** + * The password parameter of the MQTT authentication. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; +} MQTTAsync_connectData; + +#define MQTTAsync_connectData_initializer {{'M', 'Q', 'C', 'D'}, 0, NULL, {0, NULL}} + +/** + * This is a callback function which will allow the client application to update the + * connection data. + * @param data The connection data which can be modified by the application. + * @return Return a non-zero value to update the connect data, zero to keep the same data. + */ +typedef int MQTTAsync_updateConnectOptions(void* context, MQTTAsync_connectData* data); + +/** + * Sets the MQTTAsync_updateConnectOptions() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_updateConnectOptions() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setUpdateConnectOptions(MQTTAsync handle, void* context, MQTTAsync_updateConnectOptions* co); + +/** + * Sets the MQTTPersistence_beforeWrite() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setBeforePersistenceWrite(MQTTAsync handle, void* context, MQTTPersistence_beforeWrite* co); + + +/** + * Sets the MQTTPersistence_afterRead() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setAfterPersistenceRead(MQTTAsync handle, void* context, MQTTPersistence_afterRead* co); + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** A numeric code identifying the error. */ + int code; + /** Optional text explaining the error. Can be NULL. */ + const char *message; +} MQTTAsync_failureData; + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQFD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** The MQTT reason code returned. */ + enum MQTTReasonCodes reasonCode; + /** The MQTT properties on the ack, if any. */ + MQTTProperties properties; + /** A numeric code identifying the MQTT client library error. */ + int code; + /** Optional further text explaining the error. Can be NULL. */ + const char *message; + /** Packet type on which the failure occurred - used for publish QoS 1/2 exchanges*/ + int packet_type; +} MQTTAsync_failureData5; + +#define MQTTAsync_failureData5_initializer {{'M', 'Q', 'F', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, 0, NULL} + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribe, the granted QoS of the subscription returned by the server. + * Also for subscribeMany, if only 1 subscription was requested. */ + int qos; + /** For subscribeMany, if more than one subscription was requested, + * the list of granted QoSs of the subscriptions returned by the server. */ + int* qosList; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + } alt; +} MQTTAsync_successData; + + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + char struct_id[4]; /**< The eyecatcher for this structure. Will be MQSD. */ + int struct_version; /**< The version number of this structure. Will be 0 */ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + enum MQTTReasonCodes reasonCode; /**< MQTT V5 reason code returned */ + MQTTProperties properties; /**< MQTT V5 properties returned, if any */ + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } sub; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + /** For unsubscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } unsub; + } alt; +} MQTTAsync_successData5; + +#define MQTTAsync_successData5_initializer {{'M', 'Q', 'S', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer} + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onSuccess. + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess5(void* context, MQTTAsync_successData5* response); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure(void* context, MQTTAsync_failureData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onFailure. + * The application must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure5(void* context, MQTTAsync_failureData5* response); + +/** Structure to define call options. For MQTT 5.0 there is input data as well as that + * describing the response method. So there is now also a synonym ::MQTTAsync_callOptions + * to better reflect the use. This responseOptions name is kept for backward + * compatibility. + */ +typedef struct MQTTAsync_responseOptions +{ + /** The eyecatcher for this structure. Must be MQTR */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * if 0, no MQTTV5 options */ + int struct_version; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the API call fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * A token is returned from the call. It can be used to track + * the state of this request, both in the callbacks and in future calls + * such as ::MQTTAsync_waitForCompletion. + */ + MQTTAsync_token token; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /* + * MQTT V5 subscribe options, when used with subscribe only. + */ + MQTTSubscribe_options subscribeOptions; + /* + * MQTT V5 subscribe option count, when used with subscribeMany only. + * The number of entries in the subscribe_options_list array. + */ + int subscribeOptionsCount; + /* + * MQTT V5 subscribe option array, when used with subscribeMany only. + */ + MQTTSubscribe_options* subscribeOptionsList; +} MQTTAsync_responseOptions; + +#define MQTTAsync_responseOptions_initializer { {'M', 'Q', 'T', 'R'}, 1, NULL, NULL, 0, 0, NULL, NULL, MQTTProperties_initializer, MQTTSubscribe_options_initializer, 0, NULL} + +/** A synonym for responseOptions to better reflect its usage since MQTT 5.0 */ +typedef struct MQTTAsync_responseOptions MQTTAsync_callOptions; +#define MQTTAsync_callOptions_initializer MQTTAsync_responseOptions_initializer + +/** + * This function sets the global callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. If this callback is not set, an error will be returned. + * You must set this callback because otherwise there would be + * no way to deliver any incoming messages. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl, + MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc); + +/** + * This function sets the callback function for a connection lost event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed the callback functions to provide + * access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ + +LIBMQTT_API int MQTTAsync_setConnectionLostCallback(MQTTAsync handle, void* context, + MQTTAsync_connectionLost* cl); + +/** + * This function sets the callback function for a message arrived event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. You can set this to NULL if your application doesn't handle + * receipt of messages. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setMessageArrivedCallback(MQTTAsync handle, void* context, + MQTTAsync_messageArrived* ma); + +/** + * This function sets the callback function for a delivery complete event + * for a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDeliveryCompleteCallback(MQTTAsync handle, void* context, + MQTTAsync_deliveryComplete* dc); + +/** + * Sets the MQTTAsync_connected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co); + + +/** + * Reconnects a client with the previously used connect options. Connect + * must have previously been called for this to work. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_reconnect(MQTTAsync handle); + + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTAsync_persistence). See also MQTTAsync_destroy(). + * @param handle A pointer to an ::MQTTAsync handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of + * the library is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTASYNC_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTAsync_create(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTAsync_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2 or 3 + * 0 means no MQTTVersion + * 1 means no allowDisconnectedSendAtAnyTime, deleteOldestMessages, restoreMessages + * 2 means no persistQoS0 + */ + int struct_version; + /** Whether to allow messages to be sent when the client library is not connected. */ + int sendWhileDisconnected; + /** The maximum number of messages allowed to be buffered while not connected. */ + int maxBufferedMessages; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; + /** + * Allow sending of messages while disconnected before a first successful connect. + */ + int allowDisconnectedSendAtAnyTime; + /* + * When the maximum number of buffered messages is reached, delete the oldest rather than the newest. + */ + int deleteOldestMessages; + /* + * Restore messages from persistence on create - or clear it. + */ + int restoreMessages; + /* + * Persist QoS0 publish commands - an option to not persist them. + */ + int persistQoS0; +} MQTTAsync_createOptions; + +#define MQTTAsync_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_DEFAULT, 0, 0, 1, 1} + +#define MQTTAsync_createOptions_initializer5 { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_5, 0, 0, 1, 1} + + +LIBMQTT_API int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTAsync_createOptions* options); + +/** + * MQTTAsync_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTAsync_willOptions + * structure is passed in the MQTTAsync_connectOptions structure used in the + * MQTTAsync_connect() call that connects the client to the server. The pointer + * to MQTTAsync_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 indicates no binary will message support + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTAsync_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTAsync_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTAsync_willOptions; + +#define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTAsync_SSLOptions; + +#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** Utility structure where name/value pairs are needed */ +typedef struct +{ + const char* name; /**< name string */ + const char* value; /**< value string */ +} MQTTAsync_nameValue; + +/** + * MQTTAsync_connectOptions defines several settings that control the way the + * client connects to an MQTT server. Default values are set in + * MQTTAsync_connectOptions_initializer. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3 4 5 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no automatic reconnect options + * 4 signifies no binary password option (just string) + * 5 signifies no MQTTV5 properties + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + * Set to 0 if you do not want any keep alive processing. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTAsync_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This controls how many messages can be in-flight simultaneously. + */ + int maxInflight; + /** + * This is a pointer to an MQTTAsync_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTAsync_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTAsync_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTAsync_SSLOptions* ssl; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * The number of entries in the serverURIs array. + */ + int serverURIcount; + /** + * An array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a domain name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + */ + int MQTTVersion; + /** + * Reconnect automatically in the case of a connection being lost? + */ + int automaticReconnect; + /** + * Minimum retry interval in seconds. Doubled on each failed retry. + */ + int minRetryInterval; + /** + * Maximum retry interval in seconds. The doubling stops here on failed retries. + */ + int maxRetryInterval; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * MQTT V5 properties for connect + */ + MQTTProperties *connectProperties; + /** + * MQTT V5 properties for the will message in the connect + */ + MQTTProperties *willProperties; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * HTTP headers for websockets + */ + const MQTTAsync_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTAsync_connectOptions; + + +#define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + + +/** + * This function attempts to connect a previously-created client (see + * MQTTAsync_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTAsync_setCallbacks() prior to MQTTAsync_connect(). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options A pointer to a valid MQTTAsync_connectOptions + * structure. + * @return ::MQTTASYNC_SUCCESS if the client connect request was accepted. + * If the client was unable to connect to the server, an error code is + * returned via the onFailure callback, if set. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options); + +/** Options for the ::MQTTAsync_disconnect call */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTD. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. 0 signifies no V5 properties */ + int struct_version; + /** + * The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + */ + int timeout; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /** + * Reason code for MQTTV5 disconnect + */ + enum MQTTReasonCodes reasonCode; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; +} MQTTAsync_disconnectOptions; + +#define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 0, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +#define MQTTAsync_disconnectOptions_initializer5 { {'M', 'Q', 'T', 'D'}, 1, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTAsync_connectOptions.cleansession and MQTTAsync_connect()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions* options); + + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTAsync_isConnected(MQTTAsync handle); + + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTAsync_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTAsync_subscribe(MQTTAsync handle, const char* topic, int qos, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTAsync_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char* const* topic, const int* qos, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTAsync_unsubscribe(MQTTAsync handle, const char* topic, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const* topic, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to publish a message to a given topic (see also + * ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * This is optional and can be set to NULL. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_send(MQTTAsync handle, const char* destinationName, int payloadlen, const void* payload, int qos, + int retained, MQTTAsync_responseOptions* response); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTAsync_publish()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param msg A pointer to a valid MQTTAsync_message structure containing + * the payload and attributes of the message to be published. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_sendMessage(MQTTAsync handle, const char* destinationName, const MQTTAsync_message* msg, MQTTAsync_responseOptions* response); + + +/** + * This function sets a pointer to an array of tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param tokens The address of a pointer to an ::MQTTAsync_token. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTASYNC_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens); + +/** + * Tests whether a request corresponding to a token is complete. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @return 1 if the request has been completed, 0 if not. + */ +#define MQTTASYNC_TRUE 1 +LIBMQTT_API int MQTTAsync_isComplete(MQTTAsync handle, MQTTAsync_token token); + + +/** + * Waits for a request corresponding to a token to complete. This only works for + * messages with QoS greater than 0. A QoS 0 message has no MQTT token. + * This function will always return ::MQTTASYNC_SUCCESS for a QoS 0 message. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @param timeout the maximum time to wait for completion, in milliseconds + * @return ::MQTTASYNC_SUCCESS if the request has been completed in the time allocated, + * ::MQTTASYNC_FAILURE or ::MQTTASYNC_DISCONNECTED if not. + */ +LIBMQTT_API int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token token, unsigned long timeout); + + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTAsync_free() library function. + * @param msg The address of a pointer to the ::MQTTAsync_message structure + * to be freed. + */ +LIBMQTT_API void MQTTAsync_freeMessage(MQTTAsync_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTAsync_free(void* ptr); + +/** + * This function is used to allocate memory to be used or freed by the MQTT C client library, + * especially the data in the ::MQTTPersistence_afterRead and ::MQTTPersistence_beforeWrite + * callbacks. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. + * @param size The size of the memory to be allocated. + */ +LIBMQTT_API void* MQTTAsync_malloc(size_t size); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTAsync_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTAsync + * structure to be freed. + */ +LIBMQTT_API void MQTTAsync_destroy(MQTTAsync* handle); + + + +enum MQTTASYNC_TRACE_LEVELS +{ + MQTTASYNC_TRACE_MAXIMUM = 1, + MQTTASYNC_TRACE_MEDIUM, + MQTTASYNC_TRACE_MINIMUM, + MQTTASYNC_TRACE_PROTOCOL, + MQTTASYNC_TRACE_ERROR, + MQTTASYNC_TRACE_SEVERE, + MQTTASYNC_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTAsync_setTraceLevel(enum MQTTASYNC_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTAsync_traceCallback(enum MQTTASYNC_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTAsync_setTraceCallback(MQTTAsync_traceCallback* callback); + +/** + * This function returns version information about the library. + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void); + +/** + * Returns a pointer to a string representation of the error code, or NULL. + * Do not free after use. Returns NULL if the error code is unknown. + * @param code the MQTTASYNC_ return code. + * @return a static string representation of the error code. + */ +LIBMQTT_API const char* MQTTAsync_strerror(int code); + + +/*! + * @cond MQTTAsync_main + * @page async Threading + * The client application runs on several threads. + * Processing of handshaking and maintaining + * the network connection is performed in the background. + * This API is thread safe: functions may be called by multiple application + * threads. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(), + * MQTTAsync_connectionLost() and MQTTAsync_deliveryComplete()). + * In addition, some functions allow success and failure callbacks to be set + * for individual requests, in the ::MQTTAsync_responseOptions structure. Applications + * can be written as a chain of callback functions. + * + * @page callbacks Callbacks + * Any function from this API may be used within a callback. It is not advisable to + * use ::MQTTAsync_waitForCompletion within a callback, however, as it is the only + * API call that may take some time to complete, which may cause unpredictable + * behaviour. All the other API calls are intended to complete quickly, starting + * a request in the background, with success or failure notified by other callbacks. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * A log message will be written to highlight the issue, but it is up + * to the application to protect against this situation. + * + * @page auto_reconnect Automatic Reconnect + * The ability for the client library to reconnect automatically in the event + * of a connection failure was added in 1.1. The connection lost callback + * allows a flexible response to the loss of a connection, so almost any + * behaviour can be implemented in that way. Automatic reconnect does have the + * advantage of being a little simpler to use. + * + * To switch on automatic reconnect, the connect options field + * automaticReconnect should be set to non-zero. The minimum and maximum times + * before the next connection attempt can also be set, the defaults being 1 and + * 60 seconds. At each failure to reconnect, the retry interval is doubled until + * the maximum value is reached, and there it stays until the connection is + * successfully re-established whereupon it is reset. + * + * When a reconnection attempt is successful, the ::MQTTAsync_connected callback + * function is invoked, if set by calling ::MQTTAsync_setConnected. This allows + * the application to take any actions needed, such as amending subscriptions. + * + * @page offline_publish Publish While Disconnected + * This feature was not originally available because with persistence enabled, + * messages could be stored locally without ever knowing if they could be sent. + * The client application could have created the client with an erroneous broker + * address or port for instance. + * + * To enable messages to be published when the application is disconnected + * ::MQTTAsync_createWithOptions must be used instead of ::MQTTAsync_create to + * create the client object. The ::MQTTAsync_createOptions field sendWhileDisconnected + * must be set to non-zero, and the maxBufferedMessages field set as required - + * the default being 100. + * + * ::MQTTAsync_getPendingTokens can be called to return the ids of the messages + * waiting to be sent, or for which the sending process has not completed. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTAsync_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page publish Publication example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed\n"); + finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + finished = 1; +} + +void onSendFailure(void* context, MQTTAsync_failureData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message send failed token %d error code %d\n", response->token, response->code); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +void onSend(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message with token value %d delivery confirmed\n", response->token); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response ? response->code : 0); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + MQTTAsync_message pubmsg = MQTTAsync_message_initializer; + int rc; + + printf("Successful connection\n"); + opts.onSuccess = onSend; + opts.onFailure = onSendFailure; + opts.context = client; + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start sendMessage, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +int messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* m) +{ + // not expecting any messages + return 1; +} + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to create client object, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + if ((rc = MQTTAsync_setCallbacks(client, NULL, connlost, messageArrived, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callback, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (!finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + MQTTAsync_destroy(&client); + return rc; +} + + * @endcode + * @page subscribe Subscription example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int disc_finished = 0; +int subscribed = 0; +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + if (cause) + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTAsync_freeMessage(&message); + MQTTAsync_free(topicName); + return 1; +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed, rc %d\n", response->code); + disc_finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + disc_finished = 1; +} + +void onSubscribe(void* context, MQTTAsync_successData* response) +{ + printf("Subscribe succeeded\n"); + subscribed = 1; +} + +void onSubscribeFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Subscribe failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + int rc; + + printf("Successful connection\n"); + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + opts.onSuccess = onSubscribe; + opts.onFailure = onSubscribeFailure; + opts.context = client; + if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start subscribe, return code %d\n", rc); + finished = 1; + } +} + + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer; + int rc; + int ch; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) + != MQTTASYNC_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTAsync_setCallbacks(client, client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + while (!subscribed && !finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + if (finished) + goto exit; + + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + disc_opts.onSuccess = onDisconnect; + disc_opts.onFailure = onDisconnectFailure; + if ((rc = MQTTAsync_disconnect(client, &disc_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + while (!disc_finished) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + +destroy_exit: + MQTTAsync_destroy(&client); +exit: + return rc; +} + + * @endcode +* @page tracing Tracing + * + * Runtime tracing can be controlled by environment variables or API calls. + * + * #### Environment variables + * + * Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable. + * A value of ON, or stdout, prints to stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * #### Trace API calls + * + * MQTTAsync_traceCallback() is used to set a callback function which is called whenever trace + * information is available. This will be the same information as that printed if the + * environment variables were used to control the trace. + * + * The MQTTAsync_setTraceLevel() calls is used to set the maximum level of trace entries that will be + * passed to the callback function. The levels are: + * 1. ::MQTTASYNC_TRACE_MAXIMUM + * 2. ::MQTTASYNC_TRACE_MEDIUM + * 3. ::MQTTASYNC_TRACE_MINIMUM + * 4. ::MQTTASYNC_TRACE_PROTOCOL + * 5. ::MQTTASYNC_TRACE_ERROR + * 6. ::MQTTASYNC_TRACE_SEVERE + * 7. ::MQTTASYNC_TRACE_FATAL + * + * Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned. + * Choosing ::MQTTASYNC_TRACE_ERROR will cause ERROR, SEVERE and FATAL trace entries to be returned + * to the callback function. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ + +#if defined(__cplusplus) + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTAsyncUtils.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTAsyncUtils.h new file mode 100644 index 0000000..42a3145 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTAsyncUtils.h @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + +#if !defined(MQTTASYNCUTILS_H_) +#define MQTTASYNCUTILS_H_ + +#include "MQTTPacket.h" +#include "Thread.h" + +#define URI_TCP "tcp://" +#define URI_WS "ws://" +#define URI_WSS "wss://" + +enum MQTTAsync_threadStates +{ + STOPPED, STARTING, RUNNING, STOPPING +}; + +typedef struct +{ + MQTTAsync_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} qEntry; + +typedef struct +{ + int type; + MQTTAsync_onSuccess* onSuccess; + MQTTAsync_onFailure* onFailure; + MQTTAsync_onSuccess5* onSuccess5; + MQTTAsync_onFailure5* onFailure5; + MQTTAsync_token token; + void* context; + START_TIME_TYPE start_time; + MQTTProperties properties; + union + { + struct + { + int count; + char** topics; + int* qoss; + MQTTSubscribe_options opts; + MQTTSubscribe_options* optlist; + } sub; + struct + { + int count; + char** topics; + } unsub; + struct + { + char* destinationName; + int payloadlen; + void* payload; + int qos; + int retained; + } pub; + struct + { + int internal; + int timeout; + enum MQTTReasonCodes reasonCode; + } dis; + struct + { + int currentURI; + int MQTTVersion; /**< current MQTT version being used to connect */ + } conn; + } details; +} MQTTAsync_command; + +typedef struct MQTTAsync_struct +{ + char* serverURI; + int ssl; + int websocket; + Clients* c; + + /* "Global", to the client, callback definitions */ + MQTTAsync_connectionLost* cl; + MQTTAsync_messageArrived* ma; + MQTTAsync_deliveryComplete* dc; + void* clContext; /* the context to be associated with the conn lost callback*/ + void* maContext; /* the context to be associated with the msg arrived callback*/ + void* dcContext; /* the context to be associated with the deliv complete callback*/ + + MQTTAsync_connected* connected; + void* connected_context; /* the context to be associated with the connected callback*/ + + MQTTAsync_disconnected* disconnected; + void* disconnected_context; /* the context to be associated with the disconnected callback*/ + + MQTTAsync_updateConnectOptions* updateConnectOptions; + void* updateConnectOptions_context; + + /* Each time connect is called, we store the options that were used. These are reused in + any call to reconnect, or an automatic reconnect attempt */ + MQTTAsync_command connect; /* Connect operation properties */ + MQTTAsync_command disconnect; /* Disconnect operation properties */ + MQTTAsync_command* pending_write; /* Is there a socket write pending? */ + + List* responses; + unsigned int command_seqno; + + MQTTPacket* pack; + + /* added for offline buffering */ + MQTTAsync_createOptions* createOptions; + int shouldBeConnected; + int noBufferedMessages; /* the current number of buffered (publish) messages for this client */ + + /* added for automatic reconnect */ + int automaticReconnect; + int minRetryInterval; + int maxRetryInterval; + int serverURIcount; + char** serverURIs; + int connectTimeout; + + int currentInterval; + int currentIntervalBase; + START_TIME_TYPE lastConnectionFailedTime; + int retrying; + int reconnectNow; + + /* MQTT V5 properties */ + MQTTProperties* connectProps; + MQTTProperties* willProps; + +} MQTTAsyncs; + +typedef struct +{ + MQTTAsync_command command; + MQTTAsyncs* client; + unsigned int seqno; /* only used on restore */ + int not_restored; + char* key; /* if not_restored, this holds the key */ +} MQTTAsync_queuedCommand; + +void MQTTAsync_lock_mutex(mutex_type amutex); +void MQTTAsync_unlock_mutex(mutex_type amutex); +void MQTTAsync_terminate(void); +#if !defined(NO_PERSISTENCE) +int MQTTAsync_restoreCommands(MQTTAsyncs* client); +#endif +int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size); +void MQTTAsync_emptyMessageQueue(Clients* client); +void MQTTAsync_freeResponses(MQTTAsyncs* m); +void MQTTAsync_freeCommands(MQTTAsyncs* m); +int MQTTAsync_unpersistCommandsAndMessages(Clients* c); +void MQTTAsync_closeSession(Clients* client, enum MQTTReasonCodes reasonCode, MQTTProperties* props); +int MQTTAsync_disconnect1(MQTTAsync handle, const MQTTAsync_disconnectOptions* options, int internal); +int MQTTAsync_assignMsgId(MQTTAsyncs* m); +int MQTTAsync_getNoBufferedMessages(MQTTAsyncs* m); +void MQTTAsync_writeComplete(int socket, int rc); +void setRetryLoopInterval(int keepalive); + +#if defined(_WIN32) || defined(_WIN64) +#else +#define WINAPI +#endif + +thread_return_type WINAPI MQTTAsync_sendThread(void* n); +thread_return_type WINAPI MQTTAsync_receiveThread(void* n); + +#endif /* MQTTASYNCUTILS_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTClient.h new file mode 100644 index 0000000..da61357 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTClient.h @@ -0,0 +1,1945 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - remove const from eyecatchers #168 + *******************************************************************************/ + +/** + * @cond MQTTClient_internal + * @mainpage MQTT Client Library Internals + * In the beginning there was one MQTT C client library, MQTTClient, as implemented in MQTTClient.c + * This library was designed to be easy to use for applications which didn't mind if some of the calls + * blocked for a while. For instance, the MQTTClient_connect call will block until a successful + * connection has completed, or a connection has failed, which could be as long as the "connection + * timeout" interval, whose default is 30 seconds. + * + * However in mobile devices and other windowing environments, blocking on the GUI thread is a bad + * thing as it causes the user interface to freeze. Hence a new API, MQTTAsync, implemented + * in MQTTAsync.c, was devised. There are no blocking calls in this library, so it is well suited + * to GUI and mobile environments, at the expense of some extra complexity. + * + * Both libraries are designed to be sparing in the use of threads. So multiple client objects are + * handled by one or two threads, with a select call in Socket_getReadySocket(), used to determine + * when a socket has incoming data. This API is thread safe: functions may be called by multiple application + * threads, with the exception of ::MQTTClient_yield and ::MQTTClient_receive, which are intended + * for single threaded environments only. + * + * @endcond + * @cond MQTTClient_main + * @mainpage MQTT Client library for C + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An MQTT client library in C. + * + * These pages describe the original more synchronous API which might be + * considered easier to use. Some of the calls will block. For the new + * totally asynchronous API where no calls block, which is especially suitable + * for use in windowed environments, see the + * MQTT C Client Asynchronous API Documentation. + * The MQTTClient API is not thread safe, whereas the MQTTAsync API is. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions if multi-threaded (asynchronous mode) + * operation is being used (see @ref async).
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref pubsync
  • + *
  • @ref pubasync
  • + *
  • @ref subasync
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref callbacks
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENT_H) +#define MQTTCLIENT_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTCLIENT_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTCLIENT_FAILURE -1 + +/* error code -2 is MQTTCLIENT_PERSISTENCE_ERROR */ + +/** + * Return code: The client is disconnected. + */ +#define MQTTCLIENT_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTCLIENT_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTCLIENT_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTCLIENT_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTCLIENT_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTCLIENT_BAD_STRUCTURE -8 +/** + * Return code: A QoS value that falls outside of the acceptable range (0,1,2) + */ +#define MQTTCLIENT_BAD_QOS -9 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTCLIENT_SSL_NOT_SUPPORTED -10 + /** + * Return code: unrecognized MQTT version + */ + #define MQTTCLIENT_BAD_MQTT_VERSION -11 +/** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + */ +#define MQTTCLIENT_BAD_PROTOCOL -14 + /** + * Return code: option not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic on connect + */ + #define MQTTCLIENT_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 + /** + * MQTT version to connect with: 5 + */ + #define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTClient_init_options; + +#define MQTTClient_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library (0) + */ +LIBMQTT_API void MQTTClient_global_init(MQTTClient_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTClient_create(). + */ +typedef void* MQTTClient; +/** + * A value representing an MQTT message. A delivery token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTClient_publish(), + * MQTTClient_publishMessage(), + * MQTTClient_deliveryComplete(), + * MQTTClient_waitForCompletion() and + * MQTTClient_getPendingDeliveryTokens()). + */ +typedef int MQTTClient_deliveryToken; +typedef int MQTTClient_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTClient_publishMessage(), + * MQTTClient_publish(), MQTTClient_receive(), MQTTClient_freeMessage() + * and MQTTClient_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. + */ + int dup; + /** The message identifier is normally reserved for internal use by the + * MQTT client and server. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTClient_message; + +#define MQTTClient_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTClient_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTClient_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTClient_freeMessage must be called. + * To free the topic name storage, ::MQTTClient_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTClient_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTClient_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages. The function is registered with the + * client library by passing it as an argument to MQTTClient_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note:MQTTClient_deliveryComplete() is not called when messages are + * published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken dt); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTClient_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_connectionLost(void* context, char* cause); + +/** + * This function sets the callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Calling MQTTClient_setCallbacks() puts the + * client into multi-threaded mode. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. See @ref async for more information. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTClient_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTClient_messageArrived() callback + * function. This callback function must be set when you call + * MQTTClient_setCallbacks(), as otherwise there would be nowhere to deliver + * any incoming messages. + * @param dc A pointer to an MQTTClient_deliveryComplete() callback + * function. You can set this to NULL if your application publishes + * synchronously or if you do not want to check for successful delivery. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl, + MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc); + + +/** + * This is a callback function, which will be called when the a disconnect + * packet is received from the server. This applies to MQTT V5 and above only. + * @param context A pointer to the context value originally passed to + * ::MQTTClient_setDisconnected(), which contains any application-specific context. + * @param properties The MQTT V5 properties received with the disconnect, if any. + * @param reasonCode The MQTT V5 reason code received with the disconnect. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTClient_disconnected() callback function for a client. This will be called + * if a disconnect packet is received from the server. Only valid for MQTT V5 and above. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTClient_disconnected() callback + * function. NULL removes the callback setting. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setDisconnected(MQTTClient handle, void* context, MQTTClient_disconnected* co); + +/** + * This is a callback function, the MQTT V5 version of MQTTClient_deliveryComplete(). + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the completed delivery of messages. + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note: It is not called when messages are published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + * @param packet_type the last received packet type for this completion. For QoS 1 + * always PUBACK. For QoS 2 could be PUBREC or PUBCOMP. + * @param properties the MQTT V5 properties returned with the last packet from the server + * @param reasonCode the reason code returned from the server + */ +typedef void MQTTClient_published(void* context, int dt, int packet_type, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +LIBMQTT_API int MQTTClient_setPublished(MQTTClient handle, void* context, MQTTClient_published* co); + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTClient_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; +} MQTTClient_createOptions; + +#define MQTTClient_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, MQTTVERSION_DEFAULT } + +/** + * A version of :MQTTClient_create() with additional options. + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp or ssl. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @param options additional options for the create. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_createWithOptions(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTClient_createOptions* options); + +/** + * MQTTClient_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTClient_willOptions + * structure is passed in the MQTTClient_connectOptions structure used in the + * MQTTClient_connect() call that connects the client to the server. The pointer + * to MQTTClient_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 means there is no binary payload option + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload in string form. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTClient_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTClient_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTClient_willOptions; + +#define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTClient_SSLOptions; + +#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** + * MQTTClient_libraryInfo is used to store details relating to the currently used + * library such as the version in use, the time it was built and relevant openSSL + * options. + * There is one static instance of this struct in MQTTClient.c + */ + +typedef struct +{ + const char* name; + const char* value; +} MQTTClient_nameValue; + +/** + * This function returns version information about the library. + * no trace information will be returned. + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTClient_nameValue* MQTTClient_getVersionInfo(void); + +/** + * MQTTClient_connectOptions defines several settings that control the way the + * client connects to an MQTT server. + * + * Note: Default values are not defined for members of + * MQTTClient_connectOptions so it is good practice to specify all settings. + * If the MQTTClient_connectOptions structure is defined as an automatic + * variable, all members are set to random values and thus must be set by the + * client application. If the MQTTClient_connectOptions structure is defined + * as a static variable, initialization (in compliant compilers) sets all + * values to 0 (NULL for pointers). A #keepAliveInterval setting of 0 prevents + * correct operation of the client and so you must at least set a value + * for #keepAliveInterval. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3, 4, 5, 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no returned values + * 4 signifies no binary password option + * 5 signifies no maxInflightMessages and cleanstart + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTClient_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This is a boolean value that controls how many messages can be in-flight + * simultaneously. Setting reliable to true means that a published + * message must be completed (acknowledgements received) before another + * can be sent. Attempts to publish additional messages receive an + * ::MQTTCLIENT_MAX_MESSAGES_INFLIGHT return code. Setting this flag to + * false allows up to 10 messages to be in-flight. This can increase + * overall throughput in some circumstances. + */ + int reliable; + /** + * This is a pointer to an MQTTClient_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTClient_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTClient_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTClient_SSLOptions* ssl; + /** + * The number of entries in the optional serverURIs array. Defaults to 0. + */ + int serverURIcount; + /** + * An optional array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * If this list is empty (the default), the server URI specified on MQTTClient_create() + * is used. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + * MQTTVERSION_5 (5) = only try version 5.0 + */ + int MQTTVersion; + /** + * Returned from the connect when the MQTT version used to connect is 3.1.1 + */ + struct + { + const char* serverURI; /**< the serverURI connected to */ + int MQTTVersion; /**< the MQTT version used to connect with */ + int sessionPresent; /**< if the MQTT version is 3.1.1, the value of sessionPresent returned in the connack */ + } returned; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct + { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /** + * The maximum number of messages in flight + */ + int maxInflightMessages; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * HTTP headers for websockets + */ + const MQTTClient_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTClient_connectOptions; + +#define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +/** + * This function attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @return ::MQTTCLIENT_SUCCESS if the client successfully connects to the + * server. An error code is returned if the client was unable to connect to + * the server. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options); + +/** MQTT version 5.0 response information */ +typedef struct MQTTResponse +{ + int version; /* the version number of this structure */ + enum MQTTReasonCodes reasonCode; /* the MQTT 5.0 reason code returned */ + int reasonCodeCount; /* the number of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + enum MQTTReasonCodes* reasonCodes; /* a list of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + MQTTProperties* properties; /* optionally, the MQTT 5.0 properties returned */ +} MQTTResponse; + +#define MQTTResponse_initializer {1, MQTTREASONCODE_SUCCESS, 0, NULL, NULL} + +/** + * Frees the storage associated with the MQTT response. + * @param response the response structure to be freed + */ +LIBMQTT_API void MQTTResponse_free(MQTTResponse response); + +/** + * Attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using MQTT version 5.0 and the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @param connectProperties the MQTT 5.0 connect properties to use + * @param willProperties the MQTT 5.0 properties to set on the will message + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_connect5(MQTTClient handle, MQTTClient_connectOptions* options, + MQTTProperties* connectProperties, MQTTProperties* willProperties); + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTClient_connectOptions.cleansession and MQTTClient_connect()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param timeout The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTClient_disconnect(MQTTClient handle, int timeout); + +LIBMQTT_API int MQTTClient_disconnect5(MQTTClient handle, int timeout, enum MQTTReasonCodes reason, MQTTProperties* props); + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTClient_isConnected(MQTTClient handle); + + +/* Subscribe is synchronous. QoS list parameter is changed on return to granted QoSs. + Returns return code, MQTTCLIENT_SUCCESS == success, non-zero some sort of error (TBD) */ + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTClient_subscribe(MQTTClient handle, const char* topic, int qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribe5(MQTTClient handle, const char* topic, int qos, + MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribeMany5(MQTTClient handle, int count, char* const* topic, + int* qos, MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @return ::MQTTCLIENT_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTClient_unsubscribe(MQTTClient handle, const char* topic); + +/** + * This function attempts to remove an existing subscription made by the + * specified client using MQTT 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribe5(MQTTClient handle, const char* topic, MQTTProperties* props); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @return ::MQTTCLIENT_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client using MQTT version 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribeMany5(MQTTClient handle, int count, char* const* topic, MQTTProperties* props); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publishMessage()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publish(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, int qos, int retained, + MQTTClient_deliveryToken* dt); + +/** + * Attempts to publish a message to a given topic using MQTT version 5.0 (see also + * MQTTClient_publishMessage5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param properties the MQTT 5.0 properties to be used + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publish5(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, + int qos, int retained, MQTTProperties* properties, MQTTClient_deliveryToken* dt); +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publishMessage(MQTTClient handle, const char* topicName, MQTTClient_message* msg, MQTTClient_deliveryToken* dt); + + +/** + * Attempts to publish a message to the given topic using MQTT version 5.0 + * (see also + * MQTTClient_publish5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char* topicName, MQTTClient_message* msg, + MQTTClient_deliveryToken* dt); + +/** + * This function is called by the client application to synchronize execution + * of the main thread with completed publication of a message. When called, + * MQTTClient_waitForCompletion() blocks execution until the message has been + * successful delivered or the specified timeout has expired. See @ref async. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param dt The ::MQTTClient_deliveryToken that represents the message being + * tested for successful delivery. Delivery tokens are issued by the + * publishing functions MQTTClient_publish() and MQTTClient_publishMessage(). + * @param timeout The maximum time to wait in milliseconds. + * @return ::MQTTCLIENT_SUCCESS if the message was successfully delivered. + * An error code is returned if the timeout expires or there was a problem + * checking the token. + */ +LIBMQTT_API int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken dt, unsigned long timeout); + + +/** + * This function sets a pointer to an array of delivery tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param tokens The address of a pointer to an ::MQTTClient_deliveryToken. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTCLIENT_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTClient_getPendingDeliveryTokens(MQTTClient handle, MQTTClient_deliveryToken **tokens); + +/** + * When implementing a single-threaded client, call this function periodically + * to allow processing of message retries and to send MQTT keepalive pings. + * If the application is calling MQTTClient_receive() regularly, then it is + * not necessary to call this function. + */ +LIBMQTT_API void MQTTClient_yield(void); + +/** + * This function performs a synchronous receive of incoming messages. It should + * be used only when the client application has not set callback methods to + * support asynchronous receipt of messages (see @ref async and + * MQTTClient_setCallbacks()). Using this function allows a single-threaded + * client subscriber application to be written. When called, this function + * blocks until the next message arrives or the specified timeout expires + *(see also MQTTClient_yield()). + * + * Important note: The application must free() the memory allocated + * to the topic and the message when processing is complete (see + * MQTTClient_freeMessage()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The address of a pointer to a topic. This function + * allocates the memory for the topic and returns it to the application + * by setting topicName to point to the topic. + * @param topicLen The length of the topic. If the return code from this + * function is ::MQTTCLIENT_TOPICNAME_TRUNCATED, the topic contains embedded + * NULL characters and the full topic should be retrieved by using + * topicLen. + * @param message The address of a pointer to the received message. This + * function allocates the memory for the message and returns it to the + * application by setting message to point to the received message. + * The pointer is set to NULL if the timeout expires. + * @param timeout The length of time to wait for a message in milliseconds. + * @return ::MQTTCLIENT_SUCCESS or ::MQTTCLIENT_TOPICNAME_TRUNCATED if a + * message is received. ::MQTTCLIENT_SUCCESS can also indicate that the + * timeout expired, in which case message is NULL. An error code is + * returned if there was a problem trying to receive a message. + */ +LIBMQTT_API int MQTTClient_receive(MQTTClient handle, char** topicName, int* topicLen, MQTTClient_message** message, + unsigned long timeout); + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTClient_free() library function. + * @param msg The address of a pointer to the ::MQTTClient_message structure + * to be freed. + */ +LIBMQTT_API void MQTTClient_freeMessage(MQTTClient_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client libary and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTClient_free(void* ptr); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTClient_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTClient + * structure to be freed. + */ +LIBMQTT_API void MQTTClient_destroy(MQTTClient* handle); + + +enum MQTTCLIENT_TRACE_LEVELS +{ + MQTTCLIENT_TRACE_MAXIMUM = 1, + MQTTCLIENT_TRACE_MEDIUM, + MQTTCLIENT_TRACE_MINIMUM, + MQTTCLIENT_TRACE_PROTOCOL, + MQTTCLIENT_TRACE_ERROR, + MQTTCLIENT_TRACE_SEVERE, + MQTTCLIENT_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTClient_setTraceLevel(enum MQTTCLIENT_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTClient_traceCallback(enum MQTTCLIENT_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTClient_setTraceCallback(MQTTClient_traceCallback* callback); + +/** + * Sets the timeout value for un/subscribe commands when waiting for the un/suback response from + * the server. Values less than 5000 are not allowed. + * @param handle A valid client handle from a successful call to MQTTClient_create(). + * @param milliSeconds the maximum number of milliseconds to wait + * @return MQTTCLIENT_SUCCESS or MQTTCLIENT_FAILURE + */ +LIBMQTT_API int MQTTClient_setCommandTimeout(MQTTClient handle, unsigned long milliSeconds); + +/** + * Returns a pointer to the string representation of the error or NULL. + * + * Do not free after use. Returns NULL if the error code is unknown. + */ +LIBMQTT_API const char* MQTTClient_strerror(int code); + +#if defined(__cplusplus) + } +#endif + +#endif + +/*! + * @cond MQTTClient_main + * @page async Asynchronous vs synchronous client applications + * This client library supports two modes of operation. These are referred to + * as synchronous and asynchronous modes. If your application + * calls MQTTClient_setCallbacks(), this puts the client into asynchronous + * mode, otherwise it operates in synchronous mode. + * + * In synchronous mode, the client application runs on a single thread. + * Messages are published using the MQTTClient_publish() and + * MQTTClient_publishMessage() functions. To determine that a QoS1 or QoS2 + * (see @ref qos) message has been successfully delivered, the application + * must call the MQTTClient_waitForCompletion() function. An example showing + * synchronous publication is shown in @ref pubsync. Receiving messages in + * synchronous mode uses the MQTTClient_receive() function. Client applications + * must call either MQTTClient_receive() or MQTTClient_yield() relatively + * frequently in order to allow processing of acknowledgements and the MQTT + * "pings" that keep the network connection to the server alive. + * + * In asynchronous mode, the client application runs on several threads. The + * main program calls functions in the client library to publish and subscribe, + * just as for the synchronous mode. Processing of handshaking and maintaining + * the network connection is performed in the background, however. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTClient_setCallbacks() (see MQTTClient_messageArrived(), + * MQTTClient_connectionLost() and MQTTClient_deliveryComplete()). + * This API is not thread safe however - it is not possible to call it from multiple + * threads without synchronization. You can use the MQTTAsync API for that. + * + * @page callbacks Callbacks + * You must not call a function from this API from within a callback otherwise + * a deadlock might result. The only exception to this is the ability to call + * connect within the connection lost callback, to allow a reconnect. + * + * When using MQTT 5.0, you can also call connect from within the disconnected + * callback, which is invoked when the MQTT server sends a disconnect packet. + * This server behaviour is allowed in MQTT 5.0, but not in MQTT 3.1.1, so the + * disconnected callback will never be invoked if you use MQTT 3.1.1. + * + * In particular, you must make a publish call within the message arrived callback. + * These restrictions are all lifted in the + * MQTTAsync API. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, or receive not called, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * It is up to the application to protect against this situation. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTClient_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTClient_subscribe() and MQTTClient_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page pubsync Synchronous publication example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for up to %d seconds for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID); + rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); + printf("Message with delivery token %d delivered\n", token); + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + printf("Failed to disconnect, return code %d\n", rc); + MQTTClient_destroy(&client); + return rc; +} + + * @endcode + * + * @page pubasync Asynchronous publication example +@code{.c} +#include +#include +#include +#include "MQTTClient.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + deliveredtoken = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (deliveredtoken != token) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } + +destroy_exit: + MQTTClient_destroy(&client); + +exit: + return rc; +} + + * @endcode + * @page subasync Asynchronous subscription example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +volatile MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + if ((rc = MQTTClient_subscribe(client, TOPIC, QOS)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to subscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + int ch; + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + if ((rc = MQTTClient_unsubscribe(client, TOPIC)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to unsubscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } +destroy_exit: + MQTTClient_destroy(&client); +exit: + return rc; +} + + * @endcode + * @page tracing Tracing + * + * Runtime tracing is controlled by environment variables. + * + * Tracing is switched on by setting MQTT_C_CLIENT_TRACE. A value of ON, or stdout, prints to + * stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTClientPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTClientPersistence.h new file mode 100644 index 0000000..d3caae4 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTClientPersistence.h @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** + * @file + * \brief This structure represents a persistent data store, used to store + * outbound and inbound messages, in order to achieve reliable messaging. + * + * The MQTT Client persists QoS1 and QoS2 messages in order to meet the + * assurances of delivery associated with these @ref qos levels. The messages + * are saved in persistent storage + * The type and context of the persistence implementation are specified when + * the MQTT client is created (see MQTTClient_create()). The default + * persistence type (::MQTTCLIENT_PERSISTENCE_DEFAULT) uses a file system-based + * persistence mechanism. The persistence_context argument passed to + * MQTTClient_create() when using the default peristence is a string + * representing the location of the persistence directory. If the context + * argument is NULL, the working directory will be used. + * + * To use memory-based persistence, an application passes + * ::MQTTCLIENT_PERSISTENCE_NONE as the persistence_type to + * MQTTClient_create(). This can lead to message loss in certain situations, + * but can be appropriate in some cases (see @ref qos). + * + * Client applications can provide their own persistence mechanism by passing + * ::MQTTCLIENT_PERSISTENCE_USER as the persistence_type. To implement a + * custom persistence mechanism, the application must pass an initialized + * ::MQTTClient_persistence structure as the persistence_context + * argument to MQTTClient_create(). + * + * If the functions defined return an ::MQTTCLIENT_PERSISTENCE_ERROR then the + * state of the persisted data should remain as it was prior to the function + * being called. For example, if Persistence_put() returns + * ::MQTTCLIENT_PERSISTENCE_ERROR, then it is assumed tha tthe persistent store + * does not contain the data that was passed to the function. Similarly, if + * Persistence_remove() returns ::MQTTCLIENT_PERSISTENCE_ERROR then it is + * assumed that the data to be removed is still held in the persistent store. + * + * It is up to the persistence implementation to log any error information that + * may be required to diagnose a persistence mechanism failure. + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENTPERSISTENCE_H) +#define MQTTCLIENTPERSISTENCE_H +/* +/// @endcond +*/ + +/** + * This persistence_type value specifies the default file system-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_DEFAULT 0 +/** + * This persistence_type value specifies a memory-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_NONE 1 +/** + * This persistence_type value specifies an application-specific + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_USER 2 + +/** + * Application-specific persistence functions must return this error code if + * there is a problem executing the function. + */ +#define MQTTCLIENT_PERSISTENCE_ERROR -2 + +/** + * @brief Initialize the persistent store. + * + * Either open the existing persistent store for this client ID or create a new + * one if one doesn't exist. If the persistent store is already open, return + * without taking any action. + * + * An application can use the same client identifier to connect to many + * different servers. The clientid in conjunction with the + * serverURI uniquely identifies the persistence store required. + * + * @param handle The address of a pointer to a handle for this persistence + * implementation. This function must set handle to a valid reference to the + * persistence following a successful return. + * The handle pointer is passed as an argument to all the other + * persistence functions. It may include the context parameter and/or any other + * data for use by the persistence functions. + * @param clientID The client identifier for which the persistent store should + * be opened. + * @param serverURI The connection string specified when the MQTT client was + * created (see MQTTClient_create()). + * @param context A pointer to any data required to initialize the persistent + * store (see ::MQTTClient_persistence). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_open)(void** handle, const char* clientID, const char* serverURI, void* context); + +/** + * @brief Close the persistent store referred to by the handle. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_close)(void* handle); + +/** + * @brief Put the specified data into the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string used as the key for the data to be put in the store. The + * key is later used to retrieve data from the store with Persistence_get(). + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers associated with + * this key. + * @param buflens An array of lengths of the data buffers. buflen[n] + * gives the length of buffer[n]. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_put)(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); + +/** + * @brief Retrieve the specified data from the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be retrieved. This is + * the same key used to save the data to the store with Persistence_put(). + * @param buffer The address of a pointer to a buffer. This function sets the + * pointer to point at the retrieved data, if successful. + * @param buflen The address of an int that is set to the length of + * buffer by this function if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_get)(void* handle, char* key, char** buffer, int* buflen); + +/** + * @brief Remove the data for the specified key from the store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be removed from the + * store. This is the same key used to save the data to the store with + * Persistence_put(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_remove)(void* handle, char* key); + +/** + * @brief Returns the keys in this persistent data store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param keys The address of a pointer to pointers to strings. Assuming + * successful execution, this function allocates memory to hold the returned + * keys (strings used to store the data with Persistence_put()). It also + * allocates memory to hold an array of pointers to these strings. keys + * is set to point to the array of pointers to strings. + * @param nkeys A pointer to the number of keys in this persistent data store. + * This function sets the number of keys, if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_keys)(void* handle, char*** keys, int* nkeys); + +/** + * @brief Clears the persistence store, so that it no longer contains any + * persisted data. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_clear)(void* handle); + +/** + * @brief Returns whether any data has been persisted using the specified key. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key The string to be tested for existence in the store. + * @return Return 0 if the key was found in the store, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_containskey)(void* handle, char* key); + +/** + * @brief A structure containing the function pointers to a persistence + * implementation and the context or state that will be shared across all + * the persistence functions. + */ +typedef struct { + /** + * A pointer to any data required to initialize the persistent store. + */ + void* context; + /** + * A function pointer to an implementation of Persistence_open(). + */ + Persistence_open popen; + /** + * A function pointer to an implementation of Persistence_close(). + */ + Persistence_close pclose; + /** + * A function pointer to an implementation of Persistence_put(). + */ + Persistence_put pput; + /** + * A function pointer to an implementation of Persistence_get(). + */ + Persistence_get pget; + /** + * A function pointer to an implementation of Persistence_remove(). + */ + Persistence_remove premove; + /** + * A function pointer to an implementation of Persistence_keys(). + */ + Persistence_keys pkeys; + /** + * A function pointer to an implementation of Persistence_clear(). + */ + Persistence_clear pclear; + /** + * A function pointer to an implementation of Persistence_containskey(). + */ + Persistence_containskey pcontainskey; +} MQTTClient_persistence; + + +/** + * A callback which is invoked just before a write to persistence. This can be + * used to transform the data, for instance to encrypt it. + * @param context The context as set in ::MQTTAsync_setBeforePersistenceWrite + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers. + * @param buflens An array of lengths of the data buffers. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_beforeWrite(void* context, int bufcount, char* buffers[], int buflens[]); + + +/** + * A callback which is invoked just after a read from persistence. This can be + * used to transform the data, for instance to decrypt it. + * @param context The context as set in ::MQTTAsync_setAfterPersistenceRead + * @param buffer The address of a pointer to a buffer. + * @param buflen The address of an int that is the length of the buffer. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_afterRead(void* context, char** buffer, int* buflen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTExportDeclarations.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTExportDeclarations.h new file mode 100644 index 0000000..d492ef1 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTExportDeclarations.h @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 Andreas Walter + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Andreas Walter - initially moved export declarations into separate fle + *******************************************************************************/ + +#if !defined(EXPORTDECLARATIONS_H) +#define EXPORTDECLARATIONS_H + +#if defined(_WIN32) || defined(_WIN64) +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __declspec(dllexport) +# elif defined(PAHO_MQTT_IMPORTS) +# define LIBMQTT_API __declspec(dllimport) +# else +# define LIBMQTT_API +# endif +#else +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __attribute__ ((visibility ("default"))) +# else +# define LIBMQTT_API extern +# endif +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPacket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPacket.h new file mode 100644 index 0000000..658404a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPacket.h @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - big endian Linux reversed definition + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKET_H) +#define MQTTPACKET_H + +#include "Socket.h" +#if defined(OPENSSL) +#include "SSLSocket.h" +#endif +#include "LinkedList.h" +#include "Clients.h" + +typedef unsigned int bool; +typedef void* (*pf)(int, unsigned char, char*, size_t); + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" + +enum errors +{ + MQTTPACKET_BAD = -4, + MQTTPACKET_BUFFER_TOO_SHORT = -2, + MQTTPACKET_READ_ERROR = -1, + MQTTPACKET_READ_COMPLETE +}; + + +enum msgTypes +{ + CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, + PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, + PINGREQ, PINGRESP, DISCONNECT, AUTH +}; + +#if defined(__linux__) +#include +#if __BYTE_ORDER == __BIG_ENDIAN + #define REVERSED 1 +#endif +#endif + +/** + * Bitfields for the MQTT header byte. + */ +typedef union +{ + /*unsigned*/ char byte; /**< the whole byte */ +#if defined(REVERSED) + struct + { + unsigned int type : 4; /**< message type nibble */ + bool dup : 1; /**< DUP flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool retain : 1; /**< retained flag bit */ + } bits; +#else + struct + { + bool retain : 1; /**< retained flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool dup : 1; /**< DUP flag bit */ + unsigned int type : 4; /**< message type nibble */ + } bits; +#endif +} Header; + + +/** + * Data for a connect packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connect flags */ +#if defined(REVERSED) + struct + { + bool username : 1; /**< 3.1 user name */ + bool password : 1; /**< 3.1 password */ + bool willRetain : 1; /**< will retain setting */ + unsigned int willQoS : 2; /**< will QoS value */ + bool will : 1; /**< will flag */ + bool cleanstart : 1; /**< cleansession flag */ + int : 1; /**< unused */ + } bits; +#else + struct + { + int : 1; /**< unused */ + bool cleanstart : 1; /**< cleansession flag */ + bool will : 1; /**< will flag */ + unsigned int willQoS : 2; /**< will QoS value */ + bool willRetain : 1; /**< will retain setting */ + bool password : 1; /**< 3.1 password */ + bool username : 1; /**< 3.1 user name */ + } bits; +#endif + } flags; /**< connect flags byte */ + + char *Protocol, /**< MQTT protocol name */ + *clientID, /**< string client id */ + *willTopic, /**< will topic */ + *willMsg; /**< will payload */ + + int keepAliveTimer; /**< keepalive timeout value in seconds */ + unsigned char version; /**< MQTT version number */ +} Connect; + + +/** + * Data for a connack packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connack flags */ +#if defined(REVERSED) + struct + { + unsigned int reserved : 7; /**< message type nibble */ + bool sessionPresent : 1; /**< was a session found on the server? */ + } bits; +#else + struct + { + bool sessionPresent : 1; /**< was a session found on the server? */ + unsigned int reserved : 7; /**< message type nibble */ + } bits; +#endif + } flags; /**< connack flags byte */ + unsigned char rc; /**< connack reason code */ + unsigned int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Connack; + + +/** + * Data for a packet with header only. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ +} MQTTPacket; + + +/** + * Data for a suback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* qoss; /**< list of granted QoSs (MQTT 3/4) / reason codes (MQTT 5) */ +} Suback; + + +/** + * Data for an MQTT V5 unsuback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* reasonCodes; /**< list of reason codes */ +} Unsuback; + + +/** + * Data for a publish packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + char* topic; /**< topic string */ + int topiclen; + int msgId; /**< MQTT message id */ + char* payload; /**< binary payload, length delimited */ + int payloadlen; /**< payload length */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + uint8_t mask[4]; /**< the websockets mask the payload is masked with, if any */ +} Publish; + + +/** + * Data for one of the ack packets. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + unsigned char rc; /**< MQTT 5 reason code */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Ack; + +typedef Ack Puback; +typedef Ack Pubrec; +typedef Ack Pubrel; +typedef Ack Pubcomp; + +int MQTTPacket_encode(char* buf, size_t length); +int MQTTPacket_decode(networkHandles* net, size_t* value); +int readInt(char** pptr); +char* readUTF(char** pptr, char* enddata); +unsigned char readChar(char** pptr); +void writeChar(char** pptr, char c); +void writeInt(char** pptr, int anInt); +void writeUTF(char** pptr, const char* string); +void writeData(char** pptr, const void* data, int datalen); + +const char* MQTTPacket_name(int ptype); + +void* MQTTPacket_Factory(int MQTTVersion, networkHandles* net, int* error); +int MQTTPacket_send(networkHandles* net, Header header, char* buffer, size_t buflen, int free, int MQTTVersion); +int MQTTPacket_sends(networkHandles* net, Header header, PacketBuffers* buffers, int MQTTVersion); + +void* MQTTPacket_header_only(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +int MQTTPacket_send_disconnect(Clients* client, enum MQTTReasonCodes reason, MQTTProperties* props); + +void* MQTTPacket_publish(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freePublish(Publish* pack); +int MQTTPacket_send_publish(Publish* pack, int dup, int qos, int retained, networkHandles* net, const char* clientID); +int MQTTPacket_send_puback(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +void MQTTPacket_freeAck(Ack* pack); +void MQTTPacket_freeSuback(Suback* pack); +void MQTTPacket_freeUnsuback(Unsuback* pack); +int MQTTPacket_send_pubrec(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubrel(int MQTTVersion, int msgid, int dup, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubcomp(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); + +void MQTTPacket_free_packet(MQTTPacket* pack); + +void writeInt4(char** pptr, int anInt); +int readInt4(char** pptr); +void writeMQTTLenString(char** pptr, MQTTLenString lenstring); +int MQTTLenStringRead(MQTTLenString* lenstring, char** pptr, char* enddata); +int MQTTPacket_VBIlen(int rem_len); +int MQTTPacket_decodeBuf(char* buf, unsigned int* value); + +#include "MQTTPacketOut.h" + +#endif /* MQTTPACKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPacketOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPacketOut.h new file mode 100644 index 0000000..d962554 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPacketOut.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKETOUT_H) +#define MQTTPACKETOUT_H + +#include "MQTTPacket.h" + +int MQTTPacket_send_connect(Clients* client, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +void* MQTTPacket_connack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freeConnack(Connack* pack); + +int MQTTPacket_send_pingreq(networkHandles* net, const char* clientID); + +int MQTTPacket_send_subscribe(List* topics, List* qoss, MQTTSubscribe_options* opts, MQTTProperties* props, + int msgid, int dup, Clients* client); +void* MQTTPacket_suback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +int MQTTPacket_send_unsubscribe(List* topics, MQTTProperties* props, int msgid, int dup, Clients* client); +void* MQTTPacket_unsuback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPersistence.h new file mode 100644 index 0000000..ed2e0ce --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPersistence.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - async client updates + * Ian Craggs - fix for bug 432903 - queue persistence + * Ian Craggs - MQTT V5 updates + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCE_H) +#define MQTTPERSISTENCE_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include "Clients.h" +#include "MQTTProperties.h" + +/** Stem of the key for a sent PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_PUBLISH_SENT "s-" +/** Stem of the key for a sent PUBREL */ +#define PERSISTENCE_PUBREL "sc-" +/** Stem of the key for a received PUBLISH QoS2 */ +#define PERSISTENCE_PUBLISH_RECEIVED "r-" + +/** Stem of the key for a sent MQTT V5 PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_V5_PUBLISH_SENT "s5-" +/** Stem of the key for a sent MQTT V5 PUBREL */ +#define PERSISTENCE_V5_PUBREL "sc5-" +/** Stem of the key for a received MQTT V5 PUBLISH QoS2 */ +#define PERSISTENCE_V5_PUBLISH_RECEIVED "r5-" + +/** Stem of the key for an async client command */ +#define PERSISTENCE_COMMAND_KEY "c-" +/** Stem of the key for an MQTT V5 async client command */ +#define PERSISTENCE_V5_COMMAND_KEY "c5-" +/** Stem of the key for an client incoming message queue */ +#define PERSISTENCE_QUEUE_KEY "q-" +/** Stem of the key for an MQTT V5 incoming message queue */ +#define PERSISTENCE_V5_QUEUE_KEY "q5-" +/** Maximum length of a stem for a persistence key */ +#define PERSISTENCE_MAX_STEM_LENGTH 3 +/** Maximum allowed length of a persistence key */ +#define PERSISTENCE_MAX_KEY_LENGTH 9 +/** Maximum size of an integer sequence number appended to a persistence key */ +#define PERSISTENCE_SEQNO_LIMIT 1000000 /*10^(PERSISTENCE_MAX_KEY_LENGTH - PERSISTENCE_MAX_STEM_LENGTH)*/ + +int MQTTPersistence_create(MQTTClient_persistence** per, int type, void* pcontext); +int MQTTPersistence_initialize(Clients* c, const char* serverURI); +int MQTTPersistence_close(Clients* c); +int MQTTPersistence_clear(Clients* c); +int MQTTPersistence_restorePackets(Clients* c); +void* MQTTPersistence_restorePacket(int MQTTVersion, char* buffer, size_t buflen); +void MQTTPersistence_insertInOrder(List* list, void* content, size_t size); +int MQTTPersistence_putPacket(int socket, char* buf0, size_t buf0len, int count, + char** buffers, size_t* buflens, int htype, int msgId, int scr, int MQTTVersion); +int MQTTPersistence_remove(Clients* c, char* type, int qos, int msgId); +void MQTTPersistence_wrapMsgID(Clients *c); + +typedef struct +{ + char struct_id[4]; + int struct_version; + int payloadlen; + void* payload; + int qos; + int retained; + int dup; + int msgid; + MQTTProperties properties; +} MQTTPersistence_message; + +typedef struct +{ + MQTTPersistence_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} MQTTPersistence_qEntry; + +int MQTTPersistence_unpersistQueueEntry(Clients* client, MQTTPersistence_qEntry* qe); +int MQTTPersistence_persistQueueEntry(Clients* aclient, MQTTPersistence_qEntry* qe); +int MQTTPersistence_restoreMessageQueue(Clients* c); +#ifdef __cplusplus + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPersistenceDefault.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPersistenceDefault.h new file mode 100644 index 0000000..506b4da --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTPersistenceDefault.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCEDEFAULT_H) +#define MQTTPERSISTENCEDEFAULT_H + +/** 8.3 filesystem */ +#define MESSAGE_FILENAME_LENGTH 8 +/** Extension of the filename */ +#define MESSAGE_FILENAME_EXTENSION ".msg" + +/* prototypes of the functions for the default file system persistence */ +int pstopen(void** handle, const char* clientID, const char* serverURI, void* context); +int pstclose(void* handle); +int pstput(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); +int pstget(void* handle, char* key, char** buffer, int* buflen); +int pstremove(void* handle, char* key); +int pstkeys(void* handle, char*** keys, int* nkeys); +int pstclear(void* handle); +int pstcontainskey(void* handle, char* key); + +int pstmkdir(char *pPathname); + +#endif + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProperties.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProperties.h new file mode 100644 index 0000000..81b8e3a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProperties.h @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPROPERTIES_H) +#define MQTTPROPERTIES_H + +#include "MQTTExportDeclarations.h" + +#define MQTT_INVALID_PROPERTY_ID -2 + +/** The one byte MQTT V5 property indicator */ +enum MQTTPropertyCodes { + MQTTPROPERTY_CODE_PAYLOAD_FORMAT_INDICATOR = 1, /**< The value is 1 */ + MQTTPROPERTY_CODE_MESSAGE_EXPIRY_INTERVAL = 2, /**< The value is 2 */ + MQTTPROPERTY_CODE_CONTENT_TYPE = 3, /**< The value is 3 */ + MQTTPROPERTY_CODE_RESPONSE_TOPIC = 8, /**< The value is 8 */ + MQTTPROPERTY_CODE_CORRELATION_DATA = 9, /**< The value is 9 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIER = 11, /**< The value is 11 */ + MQTTPROPERTY_CODE_SESSION_EXPIRY_INTERVAL = 17, /**< The value is 17 */ + MQTTPROPERTY_CODE_ASSIGNED_CLIENT_IDENTIFER = 18,/**< The value is 18 */ + MQTTPROPERTY_CODE_SERVER_KEEP_ALIVE = 19, /**< The value is 19 */ + MQTTPROPERTY_CODE_AUTHENTICATION_METHOD = 21, /**< The value is 21 */ + MQTTPROPERTY_CODE_AUTHENTICATION_DATA = 22, /**< The value is 22 */ + MQTTPROPERTY_CODE_REQUEST_PROBLEM_INFORMATION = 23,/**< The value is 23 */ + MQTTPROPERTY_CODE_WILL_DELAY_INTERVAL = 24, /**< The value is 24 */ + MQTTPROPERTY_CODE_REQUEST_RESPONSE_INFORMATION = 25,/**< The value is 25 */ + MQTTPROPERTY_CODE_RESPONSE_INFORMATION = 26, /**< The value is 26 */ + MQTTPROPERTY_CODE_SERVER_REFERENCE = 28, /**< The value is 28 */ + MQTTPROPERTY_CODE_REASON_STRING = 31, /**< The value is 31 */ + MQTTPROPERTY_CODE_RECEIVE_MAXIMUM = 33, /**< The value is 33*/ + MQTTPROPERTY_CODE_TOPIC_ALIAS_MAXIMUM = 34, /**< The value is 34 */ + MQTTPROPERTY_CODE_TOPIC_ALIAS = 35, /**< The value is 35 */ + MQTTPROPERTY_CODE_MAXIMUM_QOS = 36, /**< The value is 36 */ + MQTTPROPERTY_CODE_RETAIN_AVAILABLE = 37, /**< The value is 37 */ + MQTTPROPERTY_CODE_USER_PROPERTY = 38, /**< The value is 38 */ + MQTTPROPERTY_CODE_MAXIMUM_PACKET_SIZE = 39, /**< The value is 39 */ + MQTTPROPERTY_CODE_WILDCARD_SUBSCRIPTION_AVAILABLE = 40,/**< The value is 40 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIERS_AVAILABLE = 41,/**< The value is 41 */ + MQTTPROPERTY_CODE_SHARED_SUBSCRIPTION_AVAILABLE = 42/**< The value is 241 */ +}; + +/** + * Returns a printable string description of an MQTT V5 property code. + * @param value an MQTT V5 property code. + * @return the printable string description of the input property code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTPropertyName(enum MQTTPropertyCodes value); + +/** The one byte MQTT V5 property type */ +enum MQTTPropertyTypes { + MQTTPROPERTY_TYPE_BYTE, + MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER, + MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER, + MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER, + MQTTPROPERTY_TYPE_BINARY_DATA, + MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING, + MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR +}; + +/** + * Returns the MQTT V5 type code of an MQTT V5 property. + * @param value an MQTT V5 property code. + * @return the MQTT V5 type code of the input property. -1 if the code was not found. + */ +LIBMQTT_API int MQTTProperty_getType(enum MQTTPropertyCodes value); + +/** + * The data for a length delimited string + */ +typedef struct +{ + int len; /**< the length of the string */ + char* data; /**< pointer to the string data */ +} MQTTLenString; + + +/** + * Structure to hold an MQTT version 5 property of any type + */ +typedef struct +{ + enum MQTTPropertyCodes identifier; /**< The MQTT V5 property id. A multi-byte integer. */ + /** The value of the property, as a union of the different possible types. */ + union { + unsigned char byte; /**< holds the value of a byte property type */ + unsigned short integer2; /**< holds the value of a 2 byte integer property type */ + unsigned int integer4; /**< holds the value of a 4 byte integer property type */ + struct { + MQTTLenString data; /**< The value of a string property, or the name of a user property. */ + MQTTLenString value; /**< The value of a user property. */ + }; + } value; +} MQTTProperty; + +/** + * MQTT version 5 property list + */ +typedef struct MQTTProperties +{ + int count; /**< number of property entries in the array */ + int max_count; /**< max number of properties that the currently allocated array can store */ + int length; /**< mbi: byte length of all properties */ + MQTTProperty *array; /**< array of properties */ +} MQTTProperties; + +#define MQTTProperties_initializer {0, 0, 0, NULL} + +/** + * Returns the length of the properties structure when serialized ready for network transmission. + * @param props an MQTT V5 property structure. + * @return the length in bytes of the properties when serialized. + */ +int MQTTProperties_len(MQTTProperties* props); + +/** + * Add a property pointer to the property array. There is no memory allocation. + * @param props The property list to add the property to. + * @param prop The property to add to the list. + * @return 0 on success, -1 on failure. + */ +LIBMQTT_API int MQTTProperties_add(MQTTProperties* props, const MQTTProperty* prop); + +/** + * Serialize the given property list to a character buffer, e.g. for writing to the network. + * @param pptr pointer to the buffer - move the pointer as we add data + * @param properties pointer to the property list, can be NULL + * @return whether the write succeeded or not: number of bytes written, or < 0 on failure. + */ +int MQTTProperties_write(char** pptr, const MQTTProperties* properties); + +/** + * Reads a property list from a character buffer into an array. + * @param properties pointer to the property list to be filled. Should be initalized but empty. + * @param pptr pointer to the character buffer. + * @param enddata pointer to the end of the character buffer so we don't read beyond. + * @return 1 if the properties were read successfully. + */ +int MQTTProperties_read(MQTTProperties* properties, char** pptr, char* enddata); + +/** + * Free all memory allocated to the property list, including any to individual properties. + * @param properties pointer to the property list. + */ +LIBMQTT_API void MQTTProperties_free(MQTTProperties* properties); + +/** + * Copy the contents of a property list, allocating additional memory if needed. + * @param props pointer to the property list. + * @return the duplicated property list. + */ +LIBMQTT_API MQTTProperties MQTTProperties_copy(const MQTTProperties* props); + +/** + * Checks if property list contains a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return 1 if found, 0 if not. + */ +LIBMQTT_API int MQTTProperties_hasProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the number of instances of a property id. Most properties can exist only once. + * User properties and subscription ids can exist more than once. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the number of times found. Can be 0. + */ +LIBMQTT_API int MQTTProperties_propertyCount(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property. The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValue(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property when it's not the only instance. + * The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValueAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +/** + * Returns a pointer to the property structure for a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns a pointer to the property structure for a specific property when it's not the only instance. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getPropertyAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +#endif /* MQTTPROPERTIES_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProtocol.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProtocol.h new file mode 100644 index 0000000..52bcd15 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProtocol.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - MQTT 3.1.1 updates + *******************************************************************************/ + +#if !defined(MQTTPROTOCOL_H) +#define MQTTPROTOCOL_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +typedef struct +{ + int socket; + Publications* p; +} pending_write; + + +typedef struct +{ + List publications; + unsigned int msgs_received; + unsigned int msgs_sent; + List pending_writes; /* for qos 0 writes not complete */ +} MQTTProtocol; + + +#include "MQTTProtocolOut.h" + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProtocolClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProtocolClient.h new file mode 100644 index 0000000..2d077af --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProtocolClient.h @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 updates + * Rong Xiang, Ian Craggs - C++ compatibility + * Ian Craggs - add debug definition of MQTTStrdup for when needed + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLCLIENT_H) +#define MQTTPROTOCOLCLIENT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Log.h" +#include "MQTTProtocol.h" +#include "Messages.h" +#include "MQTTProperties.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +int MQTTProtocol_startPublish(Clients* pubclient, Publish* publish, int qos, int retained, Messages** m); +Messages* MQTTProtocol_createMessage(Publish* publish, Messages** mm, int qos, int retained, int allocatePayload); +Publications* MQTTProtocol_storePublication(Publish* publish, int* len); +int messageIDCompare(void* a, void* b); +int MQTTProtocol_assignMsgId(Clients* client); +void MQTTProtocol_removePublication(Publications* p); +void Protocol_processPublication(Publish* publish, Clients* client, int allocatePayload); + +int MQTTProtocol_handlePublishes(void* pack, int sock); +int MQTTProtocol_handlePubacks(void* pack, int sock); +int MQTTProtocol_handlePubrecs(void* pack, int sock); +int MQTTProtocol_handlePubrels(void* pack, int sock); +int MQTTProtocol_handlePubcomps(void* pack, int sock); + +void MQTTProtocol_closeSession(Clients* c, int sendwill); +void MQTTProtocol_keepalive(START_TIME_TYPE); +void MQTTProtocol_retry(START_TIME_TYPE, int, int); +void MQTTProtocol_freeClient(Clients* client); +void MQTTProtocol_emptyMessageList(List* msgList); +void MQTTProtocol_freeMessageList(List* msgList); + +char* MQTTStrncpy(char *dest, const char* src, size_t num); +char* MQTTStrdup(const char* src); + +//#define MQTTStrdup(src) MQTTStrncpy(malloc(strlen(src)+1), src, strlen(src)+1) + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProtocolOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProtocolOut.h new file mode 100644 index 0000000..6a50155 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTProtocolOut.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - SNI support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLOUT_H) +#define MQTTPROTOCOLOUT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" +#include "Log.h" +#include "Messages.h" +#include "MQTTProtocol.h" +#include "MQTTProtocolClient.h" + +#define MQTT_DEFAULT_PORT 1883 +#define SECURE_MQTT_DEFAULT_PORT 8883 +#define WS_DEFAULT_PORT 80 + +size_t MQTTProtocol_addressPort(const char* uri, int* port, const char **topic, int default_port); +void MQTTProtocol_reconnect(const char* ip_address, Clients* client); +#if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#else +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#endif +int MQTTProtocol_handlePingresps(void* pack, int sock); +int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, int msgID, + MQTTSubscribe_options* opts, MQTTProperties* props); +int MQTTProtocol_handleSubacks(void* pack, int sock); +int MQTTProtocol_unsubscribe(Clients* client, List* topics, int msgID, MQTTProperties* props); +int MQTTProtocol_handleUnsubacks(void* pack, int sock); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTReasonCodes.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTReasonCodes.h new file mode 100644 index 0000000..2dc08ea --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTReasonCodes.h @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTREASONCODES_H) +#define MQTTREASONCODES_H + +#include "MQTTExportDeclarations.h" + +/** The MQTT V5 one byte reason code */ +enum MQTTReasonCodes { + MQTTREASONCODE_SUCCESS = 0, + MQTTREASONCODE_NORMAL_DISCONNECTION = 0, + MQTTREASONCODE_GRANTED_QOS_0 = 0, + MQTTREASONCODE_GRANTED_QOS_1 = 1, + MQTTREASONCODE_GRANTED_QOS_2 = 2, + MQTTREASONCODE_DISCONNECT_WITH_WILL_MESSAGE = 4, + MQTTREASONCODE_NO_MATCHING_SUBSCRIBERS = 16, + MQTTREASONCODE_NO_SUBSCRIPTION_FOUND = 17, + MQTTREASONCODE_CONTINUE_AUTHENTICATION = 24, + MQTTREASONCODE_RE_AUTHENTICATE = 25, + MQTTREASONCODE_UNSPECIFIED_ERROR = 128, + MQTTREASONCODE_MALFORMED_PACKET = 129, + MQTTREASONCODE_PROTOCOL_ERROR = 130, + MQTTREASONCODE_IMPLEMENTATION_SPECIFIC_ERROR = 131, + MQTTREASONCODE_UNSUPPORTED_PROTOCOL_VERSION = 132, + MQTTREASONCODE_CLIENT_IDENTIFIER_NOT_VALID = 133, + MQTTREASONCODE_BAD_USER_NAME_OR_PASSWORD = 134, + MQTTREASONCODE_NOT_AUTHORIZED = 135, + MQTTREASONCODE_SERVER_UNAVAILABLE = 136, + MQTTREASONCODE_SERVER_BUSY = 137, + MQTTREASONCODE_BANNED = 138, + MQTTREASONCODE_SERVER_SHUTTING_DOWN = 139, + MQTTREASONCODE_BAD_AUTHENTICATION_METHOD = 140, + MQTTREASONCODE_KEEP_ALIVE_TIMEOUT = 141, + MQTTREASONCODE_SESSION_TAKEN_OVER = 142, + MQTTREASONCODE_TOPIC_FILTER_INVALID = 143, + MQTTREASONCODE_TOPIC_NAME_INVALID = 144, + MQTTREASONCODE_PACKET_IDENTIFIER_IN_USE = 145, + MQTTREASONCODE_PACKET_IDENTIFIER_NOT_FOUND = 146, + MQTTREASONCODE_RECEIVE_MAXIMUM_EXCEEDED = 147, + MQTTREASONCODE_TOPIC_ALIAS_INVALID = 148, + MQTTREASONCODE_PACKET_TOO_LARGE = 149, + MQTTREASONCODE_MESSAGE_RATE_TOO_HIGH = 150, + MQTTREASONCODE_QUOTA_EXCEEDED = 151, + MQTTREASONCODE_ADMINISTRATIVE_ACTION = 152, + MQTTREASONCODE_PAYLOAD_FORMAT_INVALID = 153, + MQTTREASONCODE_RETAIN_NOT_SUPPORTED = 154, + MQTTREASONCODE_QOS_NOT_SUPPORTED = 155, + MQTTREASONCODE_USE_ANOTHER_SERVER = 156, + MQTTREASONCODE_SERVER_MOVED = 157, + MQTTREASONCODE_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158, + MQTTREASONCODE_CONNECTION_RATE_EXCEEDED = 159, + MQTTREASONCODE_MAXIMUM_CONNECT_TIME = 160, + MQTTREASONCODE_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161, + MQTTREASONCODE_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162 +}; + +/** + * Returns a printable string description of an MQTT V5 reason code. + * @param value an MQTT V5 reason code. + * @return the printable string description of the input reason code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTReasonCode_toString(enum MQTTReasonCodes value); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTSubscribeOpts.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTSubscribeOpts.h new file mode 100644 index 0000000..264e4d0 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTSubscribeOpts.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(SUBOPTS_H) +#define SUBOPTS_H + +/** The MQTT V5 subscribe options, apart from QoS which existed before V5. */ +typedef struct MQTTSubscribe_options +{ + /** The eyecatcher for this structure. Must be MQSO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0. + */ + int struct_version; + /** To not receive our own publications, set to 1. + * 0 is the original MQTT behaviour - all messages matching the subscription are received. + */ + unsigned char noLocal; + /** To keep the retain flag as on the original publish message, set to 1. + * If 0, defaults to the original MQTT behaviour where the retain flag is only set on + * publications sent by a broker if in response to a subscribe request. + */ + unsigned char retainAsPublished; + /** 0 - send retained messages at the time of the subscribe (original MQTT behaviour) + * 1 - send retained messages on subscribe only if the subscription is new + * 2 - do not send retained messages at all + */ + unsigned char retainHandling; +} MQTTSubscribe_options; + +#define MQTTSubscribe_options_initializer { {'M', 'Q', 'S', 'O'}, 0, 0, 0, 0 } + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTTime.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTTime.h new file mode 100644 index 0000000..8bd6860 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/MQTTTime.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + *******************************************************************************/ + +#if !defined(MQTTTIME_H) +#define MQTTTIME_H + +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#if WINVER >= _WIN32_WINNT_VISTA +#define START_TIME_TYPE ULONGLONG +#define START_TIME_ZERO 0 +#else +#define START_TIME_TYPE DWORD +#define START_TIME_ZERO 0 +#endif +#elif defined(AIX) +#define START_TIME_TYPE struct timespec +#define START_TIME_ZERO {0, 0} +#else +#include +#define START_TIME_TYPE struct timeval +#define START_TIME_ZERO {0, 0} +#endif + +#define ELAPSED_TIME_TYPE uint64_t +#define DIFF_TIME_TYPE int64_t + +void MQTTTime_sleep(ELAPSED_TIME_TYPE milliseconds); +START_TIME_TYPE MQTTTime_start_clock(void); +START_TIME_TYPE MQTTTime_now(void); +ELAPSED_TIME_TYPE MQTTTime_elapsed(START_TIME_TYPE milliseconds); +DIFF_TIME_TYPE MQTTTime_difftime(START_TIME_TYPE new, START_TIME_TYPE old); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Messages.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Messages.h new file mode 100644 index 0000000..58f5eae --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Messages.h @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MESSAGES_H) +#define MESSAGES_H + +#include "Log.h" + +const char* Messages_get(int, enum LOG_LEVELS); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/OsWrapper.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/OsWrapper.h new file mode 100644 index 0000000..96b629d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/OsWrapper.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016, 2017 logi.cals GmbH + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Gunter Raidl - timer support for VxWorks + * Rainer Poisel - reusability + *******************************************************************************/ + +#if !defined(OSWRAPPER_H) +#define OSWRAPPER_H + +#if defined(_WRS_KERNEL) +#include + +#define lstat stat + +typedef unsigned long useconds_t; +void usleep(useconds_t useconds); + +#define timersub(a, b, result) \ + do \ + { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) \ + { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000L; \ + } \ + } while (0) +#endif /* defined(_WRS_KERNEL) */ + +#endif /* OSWRAPPER_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/SHA1.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/SHA1.h new file mode 100644 index 0000000..3ae2f0a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/SHA1.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2018, 2019 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(SHA1_H) +#define SHA1_H + +#if defined(OPENSSL) +#include + +/** SHA-1 Digest Length */ +#define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH + +#else /* if defined(OPENSSL) */ + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +typedef struct SHA_CTX_S +{ + HCRYPTPROV hProv; + HCRYPTHASH hHash; +} SHA_CTX; +#else /* if defined(_WIN32) || defined(_WIN64) */ + +#include +typedef struct SHA_CTX_S { + uint32_t h[5]; + union { + uint32_t w[16]; + uint8_t buffer[64]; + }; + unsigned int size; + unsigned int total; +} SHA_CTX; +#endif /* else if defined(_WIN32) || defined(_WIN64) */ + +#include + +/** SHA-1 Digest Length (number of bytes in SHA1) */ +#define SHA1_DIGEST_LENGTH (160/8) + +/** + * Initializes the SHA1 hashing algorithm + * + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Update + * @see SHA1_Final + */ +int SHA1_Init(SHA_CTX *ctx); + +/** + * Updates a block to the SHA1 hash + * + * @param[in,out] ctx hashing context structure + * @param[in] data block of data to hash + * @param[in] len length of block to hash + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Update(SHA_CTX *ctx, const void *data, size_t len); + +/** + * Produce final SHA1 hash + * + * @param[out] md SHA1 hash produced (must be atleast + * @p SHA1_DIGEST_LENGTH in length) + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Final(unsigned char *md, SHA_CTX *ctx); + +#endif /* if defined(OPENSSL) */ +#endif /* SHA1_H */ + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/SSLSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/SSLSocket.h new file mode 100644 index 0000000..86273c8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/SSLSocket.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs, Allan Stockdill-Mander - initial implementation + * Ian Craggs - SNI support + * Ian Craggs - post connect checks and CApath + *******************************************************************************/ +#if !defined(SSLSOCKET_H) +#define SSLSOCKET_H + +#if defined(_WIN32) || defined(_WIN64) + #define ssl_mutex_type HANDLE +#else + #include + #include + #define ssl_mutex_type pthread_mutex_t +#endif + +#include +#include "SocketBuffer.h" +#include "Clients.h" + +#define URI_SSL "ssl://" + +/** if we should handle openssl initialization (bool_value == 1) or depend on it to be initalized externally (bool_value == 0) */ +void SSLSocket_handleOpensslInit(int bool_value); + +int SSLSocket_initialize(void); +void SSLSocket_terminate(void); +int SSLSocket_setSocketForSSL(networkHandles* net, MQTTClient_SSLOptions* opts, const char* hostname, size_t hostname_len); + +int SSLSocket_getch(SSL* ssl, int socket, char* c); +char *SSLSocket_getdata(SSL* ssl, int socket, size_t bytes, size_t* actual_len, int* rc); + +int SSLSocket_close(networkHandles* net); +int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +int SSLSocket_connect(SSL* ssl, int sock, const char* hostname, int verify, int (*cb)(const char *str, size_t len, void *u), void* u); + +int SSLSocket_getPendingRead(void); +int SSLSocket_continueWrite(pending_writes* pw); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Socket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Socket.h new file mode 100644 index 0000000..39a8158 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Socket.h @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + * Ian Craggs - async client updates + *******************************************************************************/ + +#if !defined(SOCKET_H) +#define SOCKET_H + +#include +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#include +#define MAXHOSTNAMELEN 256 +#if !defined(SSLSOCKET_H) +#undef EAGAIN +#define EAGAIN WSAEWOULDBLOCK +#undef EINTR +#define EINTR WSAEINTR +#undef EINPROGRESS +#define EINPROGRESS WSAEINPROGRESS +#undef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#undef ENOTCONN +#define ENOTCONN WSAENOTCONN +#undef ECONNRESET +#define ECONNRESET WSAECONNRESET +#undef ETIMEDOUT +#define ETIMEDOUT WAIT_TIMEOUT +#endif +#define ioctl ioctlsocket +#define socklen_t int +#else +#define INVALID_SOCKET SOCKET_ERROR +#include +#if !defined(_WRS_KERNEL) +#include +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define ULONG size_t +#endif + +#include "mutex_type.h" /* Needed for mutex_type */ + +/** socket operation completed successfully */ +#define TCPSOCKET_COMPLETE 0 +#if !defined(SOCKET_ERROR) + /** error in socket operation */ + #define SOCKET_ERROR -1 +#endif +/** must be the same as SOCKETBUFFER_INTERRUPTED */ +#define TCPSOCKET_INTERRUPTED -22 +#define SSL_FATAL -3 + +#if !defined(INET6_ADDRSTRLEN) +#define INET6_ADDRSTRLEN 46 /** only needed for gcc/cygwin on windows */ +#endif + + +#if !defined(max) +#define max(A,B) ( (A) > (B) ? (A):(B)) +#endif + +#include "LinkedList.h" + +/* + * Network write buffers for an MQTT packet + */ +typedef struct +{ + int count; /**> number of buffers/buflens/frees */ + char** buffers; /**> array of byte buffers */ + size_t* buflens; /**> array of lengths of buffers */ + int* frees; /**> array of flags indicating whether each buffer needs to be freed */ + uint8_t mask[4]; /**> websocket mask used to mask the buffer data, if any */ +} PacketBuffers; + + +/** + * Structure to hold all socket data for the module + */ +typedef struct +{ + fd_set rset, /**< socket read set (see select doc) */ + rset_saved; /**< saved socket read set */ + int maxfdp1; /**< max descriptor used +1 (again see select doc) */ + List* clientsds; /**< list of client socket descriptors */ + ListElement* cur_clientsds; /**< current client socket descriptor (iterator) */ + List* connect_pending; /**< list of sockets for which a connect is pending */ + List* write_pending; /**< list of sockets for which a write is pending */ + fd_set pending_wset; /**< socket pending write set for select */ +} Sockets; + + +void Socket_outInitialize(void); +void Socket_outTerminate(void); +int Socket_getReadySocket(int more_work, struct timeval *tp, mutex_type mutex, int* rc); +int Socket_getch(int socket, char* c); +char *Socket_getdata(int socket, size_t bytes, size_t* actual_len, int* rc); +int Socket_putdatas(int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +void Socket_close(int socket); +#if defined(__GNUC__) && defined(__linux__) +/* able to use GNU's getaddrinfo_a to make timeouts possible */ +int Socket_new(const char* addr, size_t addr_len, int port, int* socket, long timeout); +#else +int Socket_new(const char* addr, size_t addr_len, int port, int* socket); +#endif + +int Socket_noPendingWrites(int socket); +char* Socket_getpeer(int sock); + +void Socket_addPendingWrite(int socket); +void Socket_clearPendingWrite(int socket); + +typedef void Socket_writeComplete(int socket, int rc); +void Socket_setWriteCompleteCallback(Socket_writeComplete*); + +#endif /* SOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/SocketBuffer.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/SocketBuffer.h new file mode 100644 index 0000000..0fc7d6e --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/SocketBuffer.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + *******************************************************************************/ + +#if !defined(SOCKETBUFFER_H) +#define SOCKETBUFFER_H + +#if defined(_WIN32) || defined(_WIN64) +#include +#else +#include +#endif + +#if defined(OPENSSL) +#include +#endif + +#if defined(_WIN32) || defined(_WIN64) + typedef WSABUF iobuf; +#else + typedef struct iovec iobuf; +#endif + +typedef struct +{ + int socket; + unsigned int index; + size_t headerlen; + char fixed_header[5]; /**< header plus up to 4 length bytes */ + size_t buflen, /**< total length of the buffer */ + datalen; /**< current length of data in buf */ + char* buf; +} socket_queue; + +typedef struct +{ + int socket, count; + size_t total; +#if defined(OPENSSL) + SSL* ssl; +#endif + size_t bytes; + iobuf iovecs[5]; + int frees[5]; +} pending_writes; + +#define SOCKETBUFFER_COMPLETE 0 +#if !defined(SOCKET_ERROR) + #define SOCKET_ERROR -1 +#endif +#define SOCKETBUFFER_INTERRUPTED -22 /* must be the same value as TCPSOCKET_INTERRUPTED */ + +int SocketBuffer_initialize(void); +void SocketBuffer_terminate(void); +void SocketBuffer_cleanup(int socket); +char* SocketBuffer_getQueuedData(int socket, size_t bytes, size_t* actual_len); +int SocketBuffer_getQueuedChar(int socket, char* c); +void SocketBuffer_interrupted(int socket, size_t actual_len); +char* SocketBuffer_complete(int socket); +void SocketBuffer_queueChar(int socket, char c); + +#if defined(OPENSSL) +int SocketBuffer_pendingWrite(int socket, SSL* ssl, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#else +int SocketBuffer_pendingWrite(int socket, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#endif +pending_writes* SocketBuffer_getWrite(int socket); +int SocketBuffer_writeComplete(int socket); +pending_writes* SocketBuffer_updateWrite(int socket, char* topic, char* payload); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/StackTrace.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/StackTrace.h new file mode 100644 index 0000000..c4f0d43 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/StackTrace.h @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#ifndef STACKTRACE_H_ +#define STACKTRACE_H_ + +#if defined(HIGH_PERFORMANCE) +#define NOSTACKTRACE 1 +#endif + +#include +#include "Log.h" +#include "Thread.h" + +#if defined(NOSTACKTRACE) +#define FUNC_ENTRY +#define FUNC_ENTRY_NOLOG +#define FUNC_ENTRY_MED +#define FUNC_ENTRY_MAX +#define FUNC_EXIT +#define FUNC_EXIT_NOLOG +#define FUNC_EXIT_MED +#define FUNC_EXIT_MAX +#define FUNC_EXIT_RC(x) +#define FUNC_EXIT_MED_RC(x) +#define FUNC_EXIT_MAX_RC(x) +#else +#if defined(_WIN32) || defined(_WIN64) +#define inline __inline +#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM) +#else +#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM) +#endif +#endif + +void StackTrace_entry(const char* name, int line, enum LOG_LEVELS trace); +void StackTrace_exit(const char* name, int line, void* return_value, enum LOG_LEVELS trace); + +void StackTrace_printStack(FILE* dest); +char* StackTrace_get(thread_id_type, char* buf, int bufsize); + +#endif /* STACKTRACE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Thread.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Thread.h new file mode 100644 index 0000000..29903f5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Thread.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + * Ian Craggs, Allan Stockdill-Mander - async client updates + * Ian Craggs - fix for bug #420851 + * Ian Craggs - change MacOS semaphore implementation + *******************************************************************************/ + +#if !defined(THREAD_H) +#define THREAD_H + +#include "MQTTExportDeclarations.h" + +#include "MQTTClient.h" + +#include "mutex_type.h" /* Needed for mutex_type */ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define thread_type HANDLE + #define thread_id_type DWORD + #define thread_return_type DWORD + #define thread_fn LPTHREAD_START_ROUTINE + #define cond_type HANDLE + #define sem_type HANDLE + #undef ETIMEDOUT + #define ETIMEDOUT WSAETIMEDOUT +#else + #include + + #define thread_type pthread_t + #define thread_id_type pthread_t + #define thread_return_type void* + typedef thread_return_type (*thread_fn)(void*); + typedef struct { pthread_cond_t cond; pthread_mutex_t mutex; } cond_type_struct; + typedef cond_type_struct *cond_type; + #if defined(OSX) + #include + typedef dispatch_semaphore_t sem_type; + #else + #include + typedef sem_t *sem_type; + #endif + + cond_type Thread_create_cond(int*); + int Thread_signal_cond(cond_type); + int Thread_wait_cond(cond_type condvar, int timeout); + int Thread_destroy_cond(cond_type); +#endif + +LIBMQTT_API thread_type Thread_start(thread_fn, void*); + +LIBMQTT_API mutex_type Thread_create_mutex(int*); +LIBMQTT_API int Thread_lock_mutex(mutex_type); +LIBMQTT_API int Thread_unlock_mutex(mutex_type); +int Thread_destroy_mutex(mutex_type); + +LIBMQTT_API thread_id_type Thread_getid(); + +sem_type Thread_create_sem(int*); +int Thread_wait_sem(sem_type sem, int timeout); +int Thread_check_sem(sem_type sem); +int Thread_post_sem(sem_type sem); +int Thread_destroy_sem(sem_type sem); + + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Tree.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Tree.h new file mode 100644 index 0000000..dfd70ab --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/Tree.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + + +#if !defined(TREE_H) +#define TREE_H + +#include /* for size_t definition */ + +/*BE +defm defTree(T) // macro to define a tree + +def T concat Node +{ + n32 ptr T concat Node "parent" + n32 ptr T concat Node "left" + n32 ptr T concat Node "right" + n32 ptr T id2str(T) + n32 suppress "size" +} + + +def T concat Tree +{ + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + n32 dec "count" + n32 dec suppress "size" +} + +endm + +defTree(INT) +defTree(STRING) +defTree(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct NodeStruct +{ + struct NodeStruct *parent, /**< pointer to parent tree node, in case we need it */ + *child[2]; /**< pointers to child tree nodes 0 = left, 1 = right */ + void* content; /**< pointer to element content */ + size_t size; /**< size of content */ + unsigned int red : 1; +} Node; + + +/** + * Structure to hold all data for one tree + */ +typedef struct +{ + struct + { + Node *root; /**< root node pointer */ + int (*compare)(void*, void*, int); /**< comparison function */ + } index[2]; + int indexes, /**< no of indexes into tree */ + count; /**< no of items */ + size_t size; /**< heap storage used */ + unsigned int heap_tracking : 1; /**< switch on heap tracking for this tree? */ + unsigned int allow_duplicates : 1; /**< switch to allow duplicate entries */ +} Tree; + + +Tree* TreeInitialize(int(*compare)(void*, void*, int)); +void TreeInitializeNoMalloc(Tree* aTree, int(*compare)(void*, void*, int)); +void TreeAddIndex(Tree* aTree, int(*compare)(void*, void*, int)); + +void* TreeAdd(Tree* aTree, void* content, size_t size); + +void* TreeRemove(Tree* aTree, void* content); + +void* TreeRemoveKey(Tree* aTree, void* key); +void* TreeRemoveKeyIndex(Tree* aTree, void* key, int index); + +void* TreeRemoveNodeIndex(Tree* aTree, Node* aNode, int index); + +void TreeFree(Tree* aTree); + +Node* TreeFind(Tree* aTree, void* key); +Node* TreeFindIndex(Tree* aTree, void* key, int index); + +Node* TreeNextElement(Tree* aTree, Node* curnode); + +int TreeIntCompare(void* a, void* b, int); +int TreePtrCompare(void* a, void* b, int); +int TreeStringCompare(void* a, void* b, int); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/VersionInfo.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/VersionInfo.h new file mode 100644 index 0000000..b3b3e78 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/VersionInfo.h @@ -0,0 +1,7 @@ +#ifndef VERSIONINFO_H +#define VERSIONINFO_H + +#define BUILD_TIMESTAMP "2021-02-11 12:10" +#define CLIENT_VERSION "1.3.8" + +#endif /* VERSIONINFO_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/WebSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/WebSocket.h new file mode 100644 index 0000000..e9f5765 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/WebSocket.h @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2018, 2020 Wind River Systems, Inc. and others. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(WEBSOCKET_H) +#define WEBSOCKET_H + +#include "MQTTPacket.h" + +/** + * WebSocket op codes + * @{ + */ +#define WebSocket_OP_CONTINUE 0x0 /* 0000 - continue frame */ +#define WebSocket_OP_TEXT 0x1 /* 0001 - text frame */ +#define WebSocket_OP_BINARY 0x2 /* 0010 - binary frame */ +#define WebSocket_OP_CLOSE 0x8 /* 1000 - close frame */ +#define WebSocket_OP_PING 0x9 /* 1001 - ping frame */ +#define WebSocket_OP_PONG 0xA /* 1010 - pong frame */ +/** @} */ + +/** + * Various close status codes + * @{ + */ +#define WebSocket_CLOSE_NORMAL 1000 +#define WebSocket_CLOSE_GOING_AWAY 1001 +#define WebSocket_CLOSE_PROTOCOL_ERROR 1002 +#define WebSocket_CLOSE_UNKNOWN_DATA 1003 +#define WebSocket_CLOSE_RESERVED 1004 +#define WebSocket_CLOSE_NO_STATUS_CODE 1005 /* reserved: not to be used */ +#define WebSocket_CLOSE_ABNORMAL 1006 /* reserved: not to be used */ +#define WebSocket_CLOSE_BAD_DATA 1007 +#define WebSocket_CLOSE_POLICY 1008 +#define WebSocket_CLOSE_MSG_TOO_BIG 1009 +#define WebSocket_CLOSE_NO_EXTENSION 1010 +#define WebScoket_CLOSE_UNEXPECTED 1011 +#define WebSocket_CLOSE_TLS_FAIL 1015 /* reserved: not be used */ +/** @} */ + +/* closes a websocket connection */ +void WebSocket_close(networkHandles *net, int status_code, const char *reason); + +/* sends upgrade request */ +int WebSocket_connect(networkHandles *net, const char *uri); + +/* obtain data from network socket */ +int WebSocket_getch(networkHandles *net, char* c); +char *WebSocket_getdata(networkHandles *net, size_t bytes, size_t* actual_len); +size_t WebSocket_framePos(); +void WebSocket_framePosSeekTo(size_t); + +/* send data out, in websocket format only if required */ +int WebSocket_putdatas(networkHandles* net, char** buf0, size_t* buf0len, PacketBuffers* bufs); + +/* releases any resources used by the websocket system */ +void WebSocket_terminate(void); + +/* handles websocket upgrade request */ +int WebSocket_upgrade(networkHandles *net); + +/* Notify the IP address and port of the endpoint to proxy, and wait connection to endpoint */ +int WebSocket_proxy_connect( networkHandles *net, int ssl, const char *hostname); + +#endif /* WEBSOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/mutex_type.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/mutex_type.h new file mode 100644 index 0000000..1e4b9e5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/mutex_type.h @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + *******************************************************************************/ +#if !defined(_MUTEX_TYPE_H_) +#define _MUTEX_TYPE_H_ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define mutex_type HANDLE +#else + #include + #define mutex_type pthread_mutex_t* +#endif + +#endif /* _MUTEX_TYPE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/utf-8.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/utf-8.h new file mode 100644 index 0000000..a7a4270 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/include/utf-8.h @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(UTF8_H) +#define UTF8_H + +int UTF8_validate(int len, const char *data); +int UTF8_validateString(const char* string); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libAR.a new file mode 100644 index 0000000..41d916b Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libOpenSSL_s.a new file mode 100644 index 0000000..d2e48f9 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libPahoMQTT_s.a new file mode 100644 index 0000000..ba2ae24 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libar_posix_s.a new file mode 100644 index 0000000..ab35830 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libarsystem.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libarsystem.a new file mode 100644 index 0000000..d0fccdb Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/libarsystem.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/librtk_lib.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/librtk_lib.a new file mode 100644 index 0000000..cb2b224 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.34.0/SG4/librtk_lib.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/Binary.lby b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/Binary.lby new file mode 100644 index 0000000..036882d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/Binary.lby @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libAR.a new file mode 100644 index 0000000..235f5d6 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libOpenSSL_s.a new file mode 100644 index 0000000..7d34606 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libPahoMQTT_s.a new file mode 100644 index 0000000..9d44042 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libar_posix_s.a new file mode 100644 index 0000000..735fe35 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/Arm/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Base64.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Base64.h new file mode 100644 index 0000000..7022ce8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Base64.h @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2018 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(BASE64_H) +#define BASE64_H + +/** type for size of a buffer, it saves passing around @p size_t (unsigned long long or unsigned long int) */ +typedef unsigned int b64_size_t; +/** type for raw base64 data */ +typedef unsigned char b64_data_t; + +/** + * Decodes base64 data + * + * @param[out] out decoded data + * @param[in] out_len length of output buffer + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the amount of data decoded + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_decode( b64_data_t *out, b64_size_t out_len, + const char *in, b64_size_t in_len ); + +/** + * Size of buffer required to decode base64 data + * + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the decoded string would require + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_decodeLength( const char *in, b64_size_t in_len ); + +/** + * Encodes base64 data + * + * @param[out] out encode base64 string + * @param[in] out_len length of output buffer + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the amount of data encoded + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_encode( char *out, b64_size_t out_len, + const b64_data_t *in, b64_size_t in_len ); + +/** + * Size of buffer required to encode base64 data + * + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the encoded string would require + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_encodeLength( const b64_data_t *in, b64_size_t in_len ); + +#endif /* BASE64_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Clients.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Clients.h new file mode 100644 index 0000000..a3ddb1f --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Clients.h @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - add SSL support + * Ian Craggs - fix for bug 413429 - connectionLost not called + * Ian Craggs - change will payload to binary + * Ian Craggs - password to binary + * Ian Craggs - MQTT 5 support + *******************************************************************************/ + +#if !defined(CLIENTS_H) +#define CLIENTS_H + +#include +#include "MQTTTime.h" +#if defined(OPENSSL) +#if defined(_WIN32) || defined(_WIN64) +#include +#endif +#include +#endif +#include "MQTTClient.h" +#include "LinkedList.h" +#include "MQTTClientPersistence.h" + +/** + * Stored publication data to minimize copying + */ +typedef struct +{ + char *topic; + int topiclen; + char* payload; + int payloadlen; + int refcount; + uint8_t mask[4]; +} Publications; + +/** + * Client publication message data + */ +typedef struct +{ + int qos; + int retain; + int msgid; + int MQTTVersion; + MQTTProperties properties; + Publications *publish; + START_TIME_TYPE lastTouch; /**> used for retry and expiry */ + char nextMessageType; /**> PUBREC, PUBREL, PUBCOMP */ + int len; /**> length of the whole structure+data */ +} Messages; + +/** + * Client will message data + */ +typedef struct +{ + char *topic; + int payloadlen; + void *payload; + int retained; + int qos; +} willMessages; + +typedef struct +{ + int socket; + START_TIME_TYPE lastSent; + START_TIME_TYPE lastReceived; + START_TIME_TYPE lastPing; +#if defined(OPENSSL) + SSL* ssl; + SSL_CTX* ctx; + char *https_proxy; + char *https_proxy_auth; +#endif + char *http_proxy; + char *http_proxy_auth; + int websocket; /**< socket has been upgraded to use web sockets */ + char *websocket_key; + const MQTTClient_nameValue* httpHeaders; +} networkHandles; + + +/* connection states */ +/** no connection in progress, see connected value */ +#define NOT_IN_PROGRESS 0x0 +/** TCP connection in progress */ +#define TCP_IN_PROGRESS 0x1 +/** SSL connection in progress */ +#define SSL_IN_PROGRESS 0x2 +/** Websocket connection in progress */ +#define WEBSOCKET_IN_PROGRESS 0x3 +/** TCP completed, waiting for MQTT ACK */ +#define WAIT_FOR_CONNACK 0x4 +/** Proxy connection in progress */ +#define PROXY_CONNECT_IN_PROGRESS 0x5 +/** Disconnecting */ +#define DISCONNECTING -2 + +/** + * Data related to one client + */ +typedef struct +{ + char* clientID; /**< the string id of the client */ + const char* username; /**< MQTT v3.1 user name */ + int passwordlen; /**< MQTT password length */ + const void* password; /**< MQTT v3.1 binary password */ + unsigned int cleansession : 1; /**< MQTT V3 clean session flag */ + unsigned int cleanstart : 1; /**< MQTT V5 clean start flag */ + unsigned int connected : 1; /**< whether it is currently connected */ + unsigned int good : 1; /**< if we have an error on the socket we turn this off */ + unsigned int ping_outstanding : 1; + signed int connect_state : 4; + networkHandles net; /**< network info for this client */ + int msgID; /**< the MQTT message id */ + int keepAliveInterval; /**< the MQTT keep alive interval */ + int retryInterval; + int maxInflightMessages; /**< the max number of inflight outbound messages we allow */ + willMessages* will; /**< the MQTT will message, if any */ + List* inboundMsgs; /**< inbound in flight messages */ + List* outboundMsgs; /**< outbound in flight messages */ + List* messageQueue; /**< inbound complete but undelivered messages */ + unsigned int qentry_seqno; + void* phandle; /**< the persistence handle */ + MQTTClient_persistence* persistence; /**< a persistence implementation */ + MQTTPersistence_beforeWrite* beforeWrite; /**< persistence write callback */ + MQTTPersistence_afterRead* afterRead; /**< persistence read callback */ + void* beforeWrite_context; /**< context to be used with the persistence beforeWrite callbacks */ + void* afterRead_context; /**< context to be used with the persistence afterRead callback */ + void* context; /**< calling context - used when calling disconnect_internal */ + int MQTTVersion; /**< the version of MQTT being used, 3, 4 or 5 */ + int sessionExpiry; /**< MQTT 5 session expiry */ + char* httpProxy; /**< HTTP proxy for websockets */ + char* httpsProxy; /**< HTTPS proxy for websockets */ +#if defined(OPENSSL) + MQTTClient_SSLOptions *sslopts; /**< the SSL/TLS connect options */ + SSL_SESSION* session; /**< SSL session pointer for fast handhake */ +#endif +} Clients; + +int clientIDCompare(void* a, void* b); +int clientSocketCompare(void* a, void* b); + +/** + * Configuration data related to all clients + */ +typedef struct +{ + const char* version; + List* clients; +} ClientStates; + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Heap.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Heap.h new file mode 100644 index 0000000..f89a760 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Heap.h @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - use tree data structure instead of list + *******************************************************************************/ + + +#if !defined(HEAP_H) +#define HEAP_H + +#if defined(HIGH_PERFORMANCE) +#define NO_HEAP_TRACKING 1 +#endif + +#define PAHO_MEMORY_ERROR -99 + +#include "MQTTExportDeclarations.h" + +#include +#include + +#if !defined(NO_HEAP_TRACKING) + +#if !defined(TREE_C) +/** + * redefines malloc to use "mymalloc" so that heap allocation can be tracked + * @param x the size of the item to be allocated + * @return the pointer to the item allocated, or NULL + */ +#define malloc(x) mymalloc(__FILE__, __LINE__, x) + +/** + * redefines realloc to use "myrealloc" so that heap allocation can be tracked + * @param a the heap item to be reallocated + * @param b the new size of the item + * @return the new pointer to the heap item + */ +#define realloc(a, b) myrealloc(__FILE__, __LINE__, a, b) + +/** + * redefines free to use "myfree" so that heap allocation can be tracked + * @param x the size of the item to be freed + */ +#define free(x) myfree(__FILE__, __LINE__, x) + +#endif + +/** + * Information about the state of the heap. + */ +typedef struct +{ + size_t current_size; /**< current size of the heap in bytes */ + size_t max_size; /**< max size the heap has reached in bytes */ +} heap_info; + +#if defined(__cplusplus) + extern "C" { +#endif + +void* mymalloc(char*, int, size_t size); +void* myrealloc(char*, int, void* p, size_t size); +void myfree(char*, int, void* p); + +void Heap_scan(FILE* file); +int Heap_initialize(void); +void Heap_terminate(void); +LIBMQTT_API heap_info* Heap_get_info(void); +int HeapDump(FILE* file); +int HeapDumpString(FILE* file, char* str); +void* Heap_findItem(void* p); +void Heap_unlink(char* file, int line, void* p); +#ifdef __cplusplus + } +#endif + +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/LinkedList.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/LinkedList.h new file mode 100644 index 0000000..e390012 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/LinkedList.h @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + * Ian Craggs - change size types from int to size_t + *******************************************************************************/ + +#if !defined(LINKEDLIST_H) +#define LINKEDLIST_H + +#include /* for size_t definition */ + +/*BE +defm defList(T) + +def T concat Item +{ + at 4 + n32 ptr T concat Item suppress "next" + at 0 + n32 ptr T concat Item suppress "prev" + at 8 + n32 ptr T id2str(T) +} + +def T concat List +{ + n32 ptr T concat Item suppress "first" + n32 ptr T concat Item suppress "last" + n32 ptr T concat Item suppress "current" + n32 dec "count" + n32 suppress "size" +} +endm + +defList(INT) +defList(STRING) +defList(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct ListElementStruct +{ + struct ListElementStruct *prev, /**< pointer to previous list element */ + *next; /**< pointer to next list element */ + void* content; /**< pointer to element content */ +} ListElement; + + +/** + * Structure to hold all data for one list + */ +typedef struct +{ + ListElement *first, /**< first element in the list */ + *last, /**< last element in the list */ + *current; /**< current element in the list, for iteration */ + int count; /**< no of items */ + size_t size; /**< heap storage used */ +} List; + +void ListZero(List*); +List* ListInitialize(void); + +ListElement* ListAppend(List* aList, void* content, size_t size); +void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, size_t size); +ListElement* ListInsert(List* aList, void* content, size_t size, ListElement* index); + +int ListRemove(List* aList, void* content); +int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*)); +void* ListDetachHead(List* aList); +int ListRemoveHead(List* aList); +void* ListPopTail(List* aList); + +int ListDetach(List* aList, void* content); +int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*)); + +void ListFree(List* aList); +void ListEmpty(List* aList); +void ListFreeNoContent(List* aList); + +ListElement* ListNextElement(List* aList, ListElement** pos); +ListElement* ListPrevElement(List* aList, ListElement** pos); + +ListElement* ListFind(List* aList, void* content); +ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*)); + +int intcompare(void* a, void* b); +int stringcompare(void* a, void* b); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Log.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Log.h new file mode 100644 index 0000000..102e31d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Log.h @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + *******************************************************************************/ + +#if !defined(LOG_H) +#define LOG_H + +/*BE +map LOG_LEVELS +{ + "TRACE_MAXIMUM" 1 + "TRACE_MEDIUM" 2 + "TRACE_MINIMUM" 3 + "TRACE_PROTOCOL" 4 + + "ERROR" 5 + "SEVERE" 6 + "FATAL" 7 +} +BE*/ + +enum LOG_LEVELS { + INVALID_LEVEL = -1, + TRACE_MAXIMUM = 1, + TRACE_MEDIUM, + TRACE_MINIMUM, + TRACE_PROTOCOL, + LOG_ERROR, + LOG_SEVERE, + LOG_FATAL, +}; + + +/*BE +def trace_settings_type +{ + n32 map LOG_LEVELS "trace_level" + n32 dec "max_trace_entries" + n32 dec "trace_output_level" +} +BE*/ +typedef struct +{ + enum LOG_LEVELS trace_level; /**< trace level */ + int max_trace_entries; /**< max no of entries in the trace buffer */ + enum LOG_LEVELS trace_output_level; /**< trace level to output to destination */ +} trace_settings_type; + +extern trace_settings_type trace_settings; + +#define LOG_PROTOCOL TRACE_PROTOCOL +#define TRACE_MAX TRACE_MAXIMUM +#define TRACE_MIN TRACE_MINIMUM +#define TRACE_MED TRACE_MEDIUM + +typedef struct +{ + const char* name; + const char* value; +} Log_nameValue; + +int Log_initialize(Log_nameValue*); +void Log_terminate(void); + +void Log(enum LOG_LEVELS, int, const char *, ...); +void Log_stackTrace(enum LOG_LEVELS, int, int, int, const char*, int, int*); + +typedef void Log_traceCallback(enum LOG_LEVELS level, const char *message); +void Log_setTraceCallback(Log_traceCallback* callback); +void Log_setTraceLevel(enum LOG_LEVELS level); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTAsync.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTAsync.h new file mode 100644 index 0000000..f728ba5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTAsync.h @@ -0,0 +1,2345 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation + * Ian Craggs, Allan Stockdill-Mander - SSL connections + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - fix for bug 444103 - success/failure callbacks not invoked + * Ian Craggs - automatic reconnect and offline buffering (send while disconnected) + * Ian Craggs - binary will message + * Ian Craggs - binary password + * Ian Craggs - remove const on eyecatchers #168 + * Ian Craggs - MQTT 5.0 + *******************************************************************************/ + +/********************************************************************/ + +/** + * @cond MQTTAsync_main + * @mainpage Asynchronous MQTT client library for C + * + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An Asynchronous MQTT client library for C. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the Asynchronous MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions
  • + *
  • Connect the client to an MQTT server
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref publish
  • + *
  • @ref subscribe
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
  • @ref auto_reconnect
  • + *
  • @ref offline_publish
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTASYNC_H) +#define MQTTASYNC_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTASYNC_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTASYNC_FAILURE -1 + +/* error code -2 is MQTTAsync_PERSISTENCE_ERROR */ + +#define MQTTASYNC_PERSISTENCE_ERROR -2 + +/** + * Return code: The client is disconnected. + */ +#define MQTTASYNC_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTASYNC_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTASYNC_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTASYNC_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTASYNC_BAD_STRUCTURE -8 +/** + * Return code: A qos parameter is not 0, 1 or 2 + */ +#define MQTTASYNC_BAD_QOS -9 +/** + * Return code: All 65535 MQTT msgids are being used + */ +#define MQTTASYNC_NO_MORE_MSGIDS -10 +/** + * Return code: the request is being discarded when not complete + */ +#define MQTTASYNC_OPERATION_INCOMPLETE -11 +/** + * Return code: no more messages can be buffered + */ +#define MQTTASYNC_MAX_BUFFERED_MESSAGES -12 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTASYNC_SSL_NOT_SUPPORTED -13 + /** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if the TLS version of the library + * is linked with. + */ +#define MQTTASYNC_BAD_PROTOCOL -14 + /** + * Return code: don't use options for another version of MQTT + */ + #define MQTTASYNC_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the client's version of MQTT + */ + #define MQTTASYNC_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic + */ + #define MQTTASYNC_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 +/** + * MQTT version to connect with: 5 + */ +#define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTAsync_init_options; + +#define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt (0) + */ +LIBMQTT_API void MQTTAsync_global_init(MQTTAsync_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTAsync_create(). + */ +typedef void* MQTTAsync; +/** + * A value representing an MQTT message. A token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTAsync_publish(), + * MQTTAsync_publishMessage(), + * MQTTAsync_deliveryComplete(), and + * MQTTAsync_getPendingTokens()). + */ +typedef int MQTTAsync_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTAsync_publishMessage(), + * MQTTAsync_publish(), MQTTAsync_receive(), MQTTAsync_freeMessage() + * and MQTTAsync_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. This is an output parameter only. + */ + int dup; + /** The message identifier is reserved for internal use by the + * MQTT client and server. It is an output parameter only - writing + * to it will serve no purpose. It contains the MQTT message id of + * an incoming publish message. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTAsync_message; + +#define MQTTAsync_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTAsync_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTAsync_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTAsync_freeMessage must be called. + * To free the topic name storage, ::MQTTAsync_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTAsync_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTAsync_messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages to the server. The function is + * registered with the client library by passing it as an argument to MQTTAsync_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTAsync_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param token The ::MQTTAsync_token associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the tokens returned from calls to + * MQTTAsync_send() and MQTTAsync_sendMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTAsync_deliveryComplete(void* context, MQTTAsync_token token); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTAsync_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connectionLost(void* context, char* cause); + + +/** + * This is a callback function, which will be called when the client + * library successfully connects. This is superfluous when the connection + * is made in response to a MQTTAsync_connect call, because the onSuccess + * callback can be used. It is intended for use when automatic reconnect + * is enabled, so that when a reconnection attempt succeeds in the background, + * the application is notified and can take any required actions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connected(void* context, char* cause); + +/** + * This is a callback function, which will be called when the client + * library receives a disconnect packet. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param properties the properties in the disconnect packet. + * @param properties the reason code from the disconnect packet + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTAsync_disconnected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDisconnected(MQTTAsync handle, void* context, MQTTAsync_disconnected* co); + +/** The connect options that can be updated before an automatic reconnect. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQCD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name parameter. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + const char* username; + /** + * The password parameter of the MQTT authentication. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; +} MQTTAsync_connectData; + +#define MQTTAsync_connectData_initializer {{'M', 'Q', 'C', 'D'}, 0, NULL, {0, NULL}} + +/** + * This is a callback function which will allow the client application to update the + * connection data. + * @param data The connection data which can be modified by the application. + * @return Return a non-zero value to update the connect data, zero to keep the same data. + */ +typedef int MQTTAsync_updateConnectOptions(void* context, MQTTAsync_connectData* data); + +/** + * Sets the MQTTAsync_updateConnectOptions() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_updateConnectOptions() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setUpdateConnectOptions(MQTTAsync handle, void* context, MQTTAsync_updateConnectOptions* co); + +/** + * Sets the MQTTPersistence_beforeWrite() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setBeforePersistenceWrite(MQTTAsync handle, void* context, MQTTPersistence_beforeWrite* co); + + +/** + * Sets the MQTTPersistence_afterRead() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setAfterPersistenceRead(MQTTAsync handle, void* context, MQTTPersistence_afterRead* co); + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** A numeric code identifying the error. */ + int code; + /** Optional text explaining the error. Can be NULL. */ + const char *message; +} MQTTAsync_failureData; + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQFD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** The MQTT reason code returned. */ + enum MQTTReasonCodes reasonCode; + /** The MQTT properties on the ack, if any. */ + MQTTProperties properties; + /** A numeric code identifying the MQTT client library error. */ + int code; + /** Optional further text explaining the error. Can be NULL. */ + const char *message; + /** Packet type on which the failure occurred - used for publish QoS 1/2 exchanges*/ + int packet_type; +} MQTTAsync_failureData5; + +#define MQTTAsync_failureData5_initializer {{'M', 'Q', 'F', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, 0, NULL} + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribe, the granted QoS of the subscription returned by the server. + * Also for subscribeMany, if only 1 subscription was requested. */ + int qos; + /** For subscribeMany, if more than one subscription was requested, + * the list of granted QoSs of the subscriptions returned by the server. */ + int* qosList; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + } alt; +} MQTTAsync_successData; + + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + char struct_id[4]; /**< The eyecatcher for this structure. Will be MQSD. */ + int struct_version; /**< The version number of this structure. Will be 0 */ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + enum MQTTReasonCodes reasonCode; /**< MQTT V5 reason code returned */ + MQTTProperties properties; /**< MQTT V5 properties returned, if any */ + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } sub; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + /** For unsubscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } unsub; + } alt; +} MQTTAsync_successData5; + +#define MQTTAsync_successData5_initializer {{'M', 'Q', 'S', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer} + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onSuccess. + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess5(void* context, MQTTAsync_successData5* response); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure(void* context, MQTTAsync_failureData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onFailure. + * The application must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure5(void* context, MQTTAsync_failureData5* response); + +/** Structure to define call options. For MQTT 5.0 there is input data as well as that + * describing the response method. So there is now also a synonym ::MQTTAsync_callOptions + * to better reflect the use. This responseOptions name is kept for backward + * compatibility. + */ +typedef struct MQTTAsync_responseOptions +{ + /** The eyecatcher for this structure. Must be MQTR */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * if 0, no MQTTV5 options */ + int struct_version; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the API call fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * A token is returned from the call. It can be used to track + * the state of this request, both in the callbacks and in future calls + * such as ::MQTTAsync_waitForCompletion. + */ + MQTTAsync_token token; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /* + * MQTT V5 subscribe options, when used with subscribe only. + */ + MQTTSubscribe_options subscribeOptions; + /* + * MQTT V5 subscribe option count, when used with subscribeMany only. + * The number of entries in the subscribe_options_list array. + */ + int subscribeOptionsCount; + /* + * MQTT V5 subscribe option array, when used with subscribeMany only. + */ + MQTTSubscribe_options* subscribeOptionsList; +} MQTTAsync_responseOptions; + +#define MQTTAsync_responseOptions_initializer { {'M', 'Q', 'T', 'R'}, 1, NULL, NULL, 0, 0, NULL, NULL, MQTTProperties_initializer, MQTTSubscribe_options_initializer, 0, NULL} + +/** A synonym for responseOptions to better reflect its usage since MQTT 5.0 */ +typedef struct MQTTAsync_responseOptions MQTTAsync_callOptions; +#define MQTTAsync_callOptions_initializer MQTTAsync_responseOptions_initializer + +/** + * This function sets the global callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. If this callback is not set, an error will be returned. + * You must set this callback because otherwise there would be + * no way to deliver any incoming messages. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl, + MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc); + +/** + * This function sets the callback function for a connection lost event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed the callback functions to provide + * access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ + +LIBMQTT_API int MQTTAsync_setConnectionLostCallback(MQTTAsync handle, void* context, + MQTTAsync_connectionLost* cl); + +/** + * This function sets the callback function for a message arrived event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. You can set this to NULL if your application doesn't handle + * receipt of messages. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setMessageArrivedCallback(MQTTAsync handle, void* context, + MQTTAsync_messageArrived* ma); + +/** + * This function sets the callback function for a delivery complete event + * for a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDeliveryCompleteCallback(MQTTAsync handle, void* context, + MQTTAsync_deliveryComplete* dc); + +/** + * Sets the MQTTAsync_connected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co); + + +/** + * Reconnects a client with the previously used connect options. Connect + * must have previously been called for this to work. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_reconnect(MQTTAsync handle); + + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTAsync_persistence). See also MQTTAsync_destroy(). + * @param handle A pointer to an ::MQTTAsync handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of + * the library is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTASYNC_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTAsync_create(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTAsync_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2 or 3 + * 0 means no MQTTVersion + * 1 means no allowDisconnectedSendAtAnyTime, deleteOldestMessages, restoreMessages + * 2 means no persistQoS0 + */ + int struct_version; + /** Whether to allow messages to be sent when the client library is not connected. */ + int sendWhileDisconnected; + /** The maximum number of messages allowed to be buffered while not connected. */ + int maxBufferedMessages; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; + /** + * Allow sending of messages while disconnected before a first successful connect. + */ + int allowDisconnectedSendAtAnyTime; + /* + * When the maximum number of buffered messages is reached, delete the oldest rather than the newest. + */ + int deleteOldestMessages; + /* + * Restore messages from persistence on create - or clear it. + */ + int restoreMessages; + /* + * Persist QoS0 publish commands - an option to not persist them. + */ + int persistQoS0; +} MQTTAsync_createOptions; + +#define MQTTAsync_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_DEFAULT, 0, 0, 1, 1} + +#define MQTTAsync_createOptions_initializer5 { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_5, 0, 0, 1, 1} + + +LIBMQTT_API int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTAsync_createOptions* options); + +/** + * MQTTAsync_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTAsync_willOptions + * structure is passed in the MQTTAsync_connectOptions structure used in the + * MQTTAsync_connect() call that connects the client to the server. The pointer + * to MQTTAsync_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 indicates no binary will message support + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTAsync_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTAsync_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTAsync_willOptions; + +#define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTAsync_SSLOptions; + +#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** Utility structure where name/value pairs are needed */ +typedef struct +{ + const char* name; /**< name string */ + const char* value; /**< value string */ +} MQTTAsync_nameValue; + +/** + * MQTTAsync_connectOptions defines several settings that control the way the + * client connects to an MQTT server. Default values are set in + * MQTTAsync_connectOptions_initializer. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3 4 5 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no automatic reconnect options + * 4 signifies no binary password option (just string) + * 5 signifies no MQTTV5 properties + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + * Set to 0 if you do not want any keep alive processing. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTAsync_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This controls how many messages can be in-flight simultaneously. + */ + int maxInflight; + /** + * This is a pointer to an MQTTAsync_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTAsync_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTAsync_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTAsync_SSLOptions* ssl; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * The number of entries in the serverURIs array. + */ + int serverURIcount; + /** + * An array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a domain name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + */ + int MQTTVersion; + /** + * Reconnect automatically in the case of a connection being lost? + */ + int automaticReconnect; + /** + * Minimum retry interval in seconds. Doubled on each failed retry. + */ + int minRetryInterval; + /** + * Maximum retry interval in seconds. The doubling stops here on failed retries. + */ + int maxRetryInterval; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * MQTT V5 properties for connect + */ + MQTTProperties *connectProperties; + /** + * MQTT V5 properties for the will message in the connect + */ + MQTTProperties *willProperties; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * HTTP headers for websockets + */ + const MQTTAsync_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTAsync_connectOptions; + + +#define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + + +/** + * This function attempts to connect a previously-created client (see + * MQTTAsync_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTAsync_setCallbacks() prior to MQTTAsync_connect(). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options A pointer to a valid MQTTAsync_connectOptions + * structure. + * @return ::MQTTASYNC_SUCCESS if the client connect request was accepted. + * If the client was unable to connect to the server, an error code is + * returned via the onFailure callback, if set. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options); + +/** Options for the ::MQTTAsync_disconnect call */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTD. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. 0 signifies no V5 properties */ + int struct_version; + /** + * The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + */ + int timeout; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /** + * Reason code for MQTTV5 disconnect + */ + enum MQTTReasonCodes reasonCode; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; +} MQTTAsync_disconnectOptions; + +#define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 0, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +#define MQTTAsync_disconnectOptions_initializer5 { {'M', 'Q', 'T', 'D'}, 1, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTAsync_connectOptions.cleansession and MQTTAsync_connect()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions* options); + + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTAsync_isConnected(MQTTAsync handle); + + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTAsync_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTAsync_subscribe(MQTTAsync handle, const char* topic, int qos, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTAsync_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char* const* topic, const int* qos, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTAsync_unsubscribe(MQTTAsync handle, const char* topic, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const* topic, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to publish a message to a given topic (see also + * ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * This is optional and can be set to NULL. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_send(MQTTAsync handle, const char* destinationName, int payloadlen, const void* payload, int qos, + int retained, MQTTAsync_responseOptions* response); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTAsync_publish()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param msg A pointer to a valid MQTTAsync_message structure containing + * the payload and attributes of the message to be published. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_sendMessage(MQTTAsync handle, const char* destinationName, const MQTTAsync_message* msg, MQTTAsync_responseOptions* response); + + +/** + * This function sets a pointer to an array of tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param tokens The address of a pointer to an ::MQTTAsync_token. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTASYNC_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens); + +/** + * Tests whether a request corresponding to a token is complete. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @return 1 if the request has been completed, 0 if not. + */ +#define MQTTASYNC_TRUE 1 +LIBMQTT_API int MQTTAsync_isComplete(MQTTAsync handle, MQTTAsync_token token); + + +/** + * Waits for a request corresponding to a token to complete. This only works for + * messages with QoS greater than 0. A QoS 0 message has no MQTT token. + * This function will always return ::MQTTASYNC_SUCCESS for a QoS 0 message. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @param timeout the maximum time to wait for completion, in milliseconds + * @return ::MQTTASYNC_SUCCESS if the request has been completed in the time allocated, + * ::MQTTASYNC_FAILURE or ::MQTTASYNC_DISCONNECTED if not. + */ +LIBMQTT_API int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token token, unsigned long timeout); + + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTAsync_free() library function. + * @param msg The address of a pointer to the ::MQTTAsync_message structure + * to be freed. + */ +LIBMQTT_API void MQTTAsync_freeMessage(MQTTAsync_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTAsync_free(void* ptr); + +/** + * This function is used to allocate memory to be used or freed by the MQTT C client library, + * especially the data in the ::MQTTPersistence_afterRead and ::MQTTPersistence_beforeWrite + * callbacks. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. + * @param size The size of the memory to be allocated. + */ +LIBMQTT_API void* MQTTAsync_malloc(size_t size); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTAsync_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTAsync + * structure to be freed. + */ +LIBMQTT_API void MQTTAsync_destroy(MQTTAsync* handle); + + + +enum MQTTASYNC_TRACE_LEVELS +{ + MQTTASYNC_TRACE_MAXIMUM = 1, + MQTTASYNC_TRACE_MEDIUM, + MQTTASYNC_TRACE_MINIMUM, + MQTTASYNC_TRACE_PROTOCOL, + MQTTASYNC_TRACE_ERROR, + MQTTASYNC_TRACE_SEVERE, + MQTTASYNC_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTAsync_setTraceLevel(enum MQTTASYNC_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTAsync_traceCallback(enum MQTTASYNC_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTAsync_setTraceCallback(MQTTAsync_traceCallback* callback); + +/** + * This function returns version information about the library. + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void); + +/** + * Returns a pointer to a string representation of the error code, or NULL. + * Do not free after use. Returns NULL if the error code is unknown. + * @param code the MQTTASYNC_ return code. + * @return a static string representation of the error code. + */ +LIBMQTT_API const char* MQTTAsync_strerror(int code); + + +/*! + * @cond MQTTAsync_main + * @page async Threading + * The client application runs on several threads. + * Processing of handshaking and maintaining + * the network connection is performed in the background. + * This API is thread safe: functions may be called by multiple application + * threads. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(), + * MQTTAsync_connectionLost() and MQTTAsync_deliveryComplete()). + * In addition, some functions allow success and failure callbacks to be set + * for individual requests, in the ::MQTTAsync_responseOptions structure. Applications + * can be written as a chain of callback functions. + * + * @page callbacks Callbacks + * Any function from this API may be used within a callback. It is not advisable to + * use ::MQTTAsync_waitForCompletion within a callback, however, as it is the only + * API call that may take some time to complete, which may cause unpredictable + * behaviour. All the other API calls are intended to complete quickly, starting + * a request in the background, with success or failure notified by other callbacks. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * A log message will be written to highlight the issue, but it is up + * to the application to protect against this situation. + * + * @page auto_reconnect Automatic Reconnect + * The ability for the client library to reconnect automatically in the event + * of a connection failure was added in 1.1. The connection lost callback + * allows a flexible response to the loss of a connection, so almost any + * behaviour can be implemented in that way. Automatic reconnect does have the + * advantage of being a little simpler to use. + * + * To switch on automatic reconnect, the connect options field + * automaticReconnect should be set to non-zero. The minimum and maximum times + * before the next connection attempt can also be set, the defaults being 1 and + * 60 seconds. At each failure to reconnect, the retry interval is doubled until + * the maximum value is reached, and there it stays until the connection is + * successfully re-established whereupon it is reset. + * + * When a reconnection attempt is successful, the ::MQTTAsync_connected callback + * function is invoked, if set by calling ::MQTTAsync_setConnected. This allows + * the application to take any actions needed, such as amending subscriptions. + * + * @page offline_publish Publish While Disconnected + * This feature was not originally available because with persistence enabled, + * messages could be stored locally without ever knowing if they could be sent. + * The client application could have created the client with an erroneous broker + * address or port for instance. + * + * To enable messages to be published when the application is disconnected + * ::MQTTAsync_createWithOptions must be used instead of ::MQTTAsync_create to + * create the client object. The ::MQTTAsync_createOptions field sendWhileDisconnected + * must be set to non-zero, and the maxBufferedMessages field set as required - + * the default being 100. + * + * ::MQTTAsync_getPendingTokens can be called to return the ids of the messages + * waiting to be sent, or for which the sending process has not completed. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTAsync_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page publish Publication example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed\n"); + finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + finished = 1; +} + +void onSendFailure(void* context, MQTTAsync_failureData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message send failed token %d error code %d\n", response->token, response->code); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +void onSend(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message with token value %d delivery confirmed\n", response->token); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response ? response->code : 0); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + MQTTAsync_message pubmsg = MQTTAsync_message_initializer; + int rc; + + printf("Successful connection\n"); + opts.onSuccess = onSend; + opts.onFailure = onSendFailure; + opts.context = client; + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start sendMessage, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +int messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* m) +{ + // not expecting any messages + return 1; +} + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to create client object, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + if ((rc = MQTTAsync_setCallbacks(client, NULL, connlost, messageArrived, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callback, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (!finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + MQTTAsync_destroy(&client); + return rc; +} + + * @endcode + * @page subscribe Subscription example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int disc_finished = 0; +int subscribed = 0; +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + if (cause) + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTAsync_freeMessage(&message); + MQTTAsync_free(topicName); + return 1; +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed, rc %d\n", response->code); + disc_finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + disc_finished = 1; +} + +void onSubscribe(void* context, MQTTAsync_successData* response) +{ + printf("Subscribe succeeded\n"); + subscribed = 1; +} + +void onSubscribeFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Subscribe failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + int rc; + + printf("Successful connection\n"); + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + opts.onSuccess = onSubscribe; + opts.onFailure = onSubscribeFailure; + opts.context = client; + if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start subscribe, return code %d\n", rc); + finished = 1; + } +} + + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer; + int rc; + int ch; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) + != MQTTASYNC_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTAsync_setCallbacks(client, client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + while (!subscribed && !finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + if (finished) + goto exit; + + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + disc_opts.onSuccess = onDisconnect; + disc_opts.onFailure = onDisconnectFailure; + if ((rc = MQTTAsync_disconnect(client, &disc_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + while (!disc_finished) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + +destroy_exit: + MQTTAsync_destroy(&client); +exit: + return rc; +} + + * @endcode +* @page tracing Tracing + * + * Runtime tracing can be controlled by environment variables or API calls. + * + * #### Environment variables + * + * Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable. + * A value of ON, or stdout, prints to stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * #### Trace API calls + * + * MQTTAsync_traceCallback() is used to set a callback function which is called whenever trace + * information is available. This will be the same information as that printed if the + * environment variables were used to control the trace. + * + * The MQTTAsync_setTraceLevel() calls is used to set the maximum level of trace entries that will be + * passed to the callback function. The levels are: + * 1. ::MQTTASYNC_TRACE_MAXIMUM + * 2. ::MQTTASYNC_TRACE_MEDIUM + * 3. ::MQTTASYNC_TRACE_MINIMUM + * 4. ::MQTTASYNC_TRACE_PROTOCOL + * 5. ::MQTTASYNC_TRACE_ERROR + * 6. ::MQTTASYNC_TRACE_SEVERE + * 7. ::MQTTASYNC_TRACE_FATAL + * + * Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned. + * Choosing ::MQTTASYNC_TRACE_ERROR will cause ERROR, SEVERE and FATAL trace entries to be returned + * to the callback function. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ + +#if defined(__cplusplus) + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTAsyncUtils.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTAsyncUtils.h new file mode 100644 index 0000000..42a3145 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTAsyncUtils.h @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + +#if !defined(MQTTASYNCUTILS_H_) +#define MQTTASYNCUTILS_H_ + +#include "MQTTPacket.h" +#include "Thread.h" + +#define URI_TCP "tcp://" +#define URI_WS "ws://" +#define URI_WSS "wss://" + +enum MQTTAsync_threadStates +{ + STOPPED, STARTING, RUNNING, STOPPING +}; + +typedef struct +{ + MQTTAsync_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} qEntry; + +typedef struct +{ + int type; + MQTTAsync_onSuccess* onSuccess; + MQTTAsync_onFailure* onFailure; + MQTTAsync_onSuccess5* onSuccess5; + MQTTAsync_onFailure5* onFailure5; + MQTTAsync_token token; + void* context; + START_TIME_TYPE start_time; + MQTTProperties properties; + union + { + struct + { + int count; + char** topics; + int* qoss; + MQTTSubscribe_options opts; + MQTTSubscribe_options* optlist; + } sub; + struct + { + int count; + char** topics; + } unsub; + struct + { + char* destinationName; + int payloadlen; + void* payload; + int qos; + int retained; + } pub; + struct + { + int internal; + int timeout; + enum MQTTReasonCodes reasonCode; + } dis; + struct + { + int currentURI; + int MQTTVersion; /**< current MQTT version being used to connect */ + } conn; + } details; +} MQTTAsync_command; + +typedef struct MQTTAsync_struct +{ + char* serverURI; + int ssl; + int websocket; + Clients* c; + + /* "Global", to the client, callback definitions */ + MQTTAsync_connectionLost* cl; + MQTTAsync_messageArrived* ma; + MQTTAsync_deliveryComplete* dc; + void* clContext; /* the context to be associated with the conn lost callback*/ + void* maContext; /* the context to be associated with the msg arrived callback*/ + void* dcContext; /* the context to be associated with the deliv complete callback*/ + + MQTTAsync_connected* connected; + void* connected_context; /* the context to be associated with the connected callback*/ + + MQTTAsync_disconnected* disconnected; + void* disconnected_context; /* the context to be associated with the disconnected callback*/ + + MQTTAsync_updateConnectOptions* updateConnectOptions; + void* updateConnectOptions_context; + + /* Each time connect is called, we store the options that were used. These are reused in + any call to reconnect, or an automatic reconnect attempt */ + MQTTAsync_command connect; /* Connect operation properties */ + MQTTAsync_command disconnect; /* Disconnect operation properties */ + MQTTAsync_command* pending_write; /* Is there a socket write pending? */ + + List* responses; + unsigned int command_seqno; + + MQTTPacket* pack; + + /* added for offline buffering */ + MQTTAsync_createOptions* createOptions; + int shouldBeConnected; + int noBufferedMessages; /* the current number of buffered (publish) messages for this client */ + + /* added for automatic reconnect */ + int automaticReconnect; + int minRetryInterval; + int maxRetryInterval; + int serverURIcount; + char** serverURIs; + int connectTimeout; + + int currentInterval; + int currentIntervalBase; + START_TIME_TYPE lastConnectionFailedTime; + int retrying; + int reconnectNow; + + /* MQTT V5 properties */ + MQTTProperties* connectProps; + MQTTProperties* willProps; + +} MQTTAsyncs; + +typedef struct +{ + MQTTAsync_command command; + MQTTAsyncs* client; + unsigned int seqno; /* only used on restore */ + int not_restored; + char* key; /* if not_restored, this holds the key */ +} MQTTAsync_queuedCommand; + +void MQTTAsync_lock_mutex(mutex_type amutex); +void MQTTAsync_unlock_mutex(mutex_type amutex); +void MQTTAsync_terminate(void); +#if !defined(NO_PERSISTENCE) +int MQTTAsync_restoreCommands(MQTTAsyncs* client); +#endif +int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size); +void MQTTAsync_emptyMessageQueue(Clients* client); +void MQTTAsync_freeResponses(MQTTAsyncs* m); +void MQTTAsync_freeCommands(MQTTAsyncs* m); +int MQTTAsync_unpersistCommandsAndMessages(Clients* c); +void MQTTAsync_closeSession(Clients* client, enum MQTTReasonCodes reasonCode, MQTTProperties* props); +int MQTTAsync_disconnect1(MQTTAsync handle, const MQTTAsync_disconnectOptions* options, int internal); +int MQTTAsync_assignMsgId(MQTTAsyncs* m); +int MQTTAsync_getNoBufferedMessages(MQTTAsyncs* m); +void MQTTAsync_writeComplete(int socket, int rc); +void setRetryLoopInterval(int keepalive); + +#if defined(_WIN32) || defined(_WIN64) +#else +#define WINAPI +#endif + +thread_return_type WINAPI MQTTAsync_sendThread(void* n); +thread_return_type WINAPI MQTTAsync_receiveThread(void* n); + +#endif /* MQTTASYNCUTILS_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTClient.h new file mode 100644 index 0000000..da61357 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTClient.h @@ -0,0 +1,1945 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - remove const from eyecatchers #168 + *******************************************************************************/ + +/** + * @cond MQTTClient_internal + * @mainpage MQTT Client Library Internals + * In the beginning there was one MQTT C client library, MQTTClient, as implemented in MQTTClient.c + * This library was designed to be easy to use for applications which didn't mind if some of the calls + * blocked for a while. For instance, the MQTTClient_connect call will block until a successful + * connection has completed, or a connection has failed, which could be as long as the "connection + * timeout" interval, whose default is 30 seconds. + * + * However in mobile devices and other windowing environments, blocking on the GUI thread is a bad + * thing as it causes the user interface to freeze. Hence a new API, MQTTAsync, implemented + * in MQTTAsync.c, was devised. There are no blocking calls in this library, so it is well suited + * to GUI and mobile environments, at the expense of some extra complexity. + * + * Both libraries are designed to be sparing in the use of threads. So multiple client objects are + * handled by one or two threads, with a select call in Socket_getReadySocket(), used to determine + * when a socket has incoming data. This API is thread safe: functions may be called by multiple application + * threads, with the exception of ::MQTTClient_yield and ::MQTTClient_receive, which are intended + * for single threaded environments only. + * + * @endcond + * @cond MQTTClient_main + * @mainpage MQTT Client library for C + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An MQTT client library in C. + * + * These pages describe the original more synchronous API which might be + * considered easier to use. Some of the calls will block. For the new + * totally asynchronous API where no calls block, which is especially suitable + * for use in windowed environments, see the + * MQTT C Client Asynchronous API Documentation. + * The MQTTClient API is not thread safe, whereas the MQTTAsync API is. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions if multi-threaded (asynchronous mode) + * operation is being used (see @ref async).
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref pubsync
  • + *
  • @ref pubasync
  • + *
  • @ref subasync
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref callbacks
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENT_H) +#define MQTTCLIENT_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTCLIENT_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTCLIENT_FAILURE -1 + +/* error code -2 is MQTTCLIENT_PERSISTENCE_ERROR */ + +/** + * Return code: The client is disconnected. + */ +#define MQTTCLIENT_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTCLIENT_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTCLIENT_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTCLIENT_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTCLIENT_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTCLIENT_BAD_STRUCTURE -8 +/** + * Return code: A QoS value that falls outside of the acceptable range (0,1,2) + */ +#define MQTTCLIENT_BAD_QOS -9 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTCLIENT_SSL_NOT_SUPPORTED -10 + /** + * Return code: unrecognized MQTT version + */ + #define MQTTCLIENT_BAD_MQTT_VERSION -11 +/** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + */ +#define MQTTCLIENT_BAD_PROTOCOL -14 + /** + * Return code: option not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic on connect + */ + #define MQTTCLIENT_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 + /** + * MQTT version to connect with: 5 + */ + #define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTClient_init_options; + +#define MQTTClient_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library (0) + */ +LIBMQTT_API void MQTTClient_global_init(MQTTClient_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTClient_create(). + */ +typedef void* MQTTClient; +/** + * A value representing an MQTT message. A delivery token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTClient_publish(), + * MQTTClient_publishMessage(), + * MQTTClient_deliveryComplete(), + * MQTTClient_waitForCompletion() and + * MQTTClient_getPendingDeliveryTokens()). + */ +typedef int MQTTClient_deliveryToken; +typedef int MQTTClient_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTClient_publishMessage(), + * MQTTClient_publish(), MQTTClient_receive(), MQTTClient_freeMessage() + * and MQTTClient_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. + */ + int dup; + /** The message identifier is normally reserved for internal use by the + * MQTT client and server. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTClient_message; + +#define MQTTClient_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTClient_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTClient_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTClient_freeMessage must be called. + * To free the topic name storage, ::MQTTClient_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTClient_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTClient_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages. The function is registered with the + * client library by passing it as an argument to MQTTClient_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note:MQTTClient_deliveryComplete() is not called when messages are + * published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken dt); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTClient_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_connectionLost(void* context, char* cause); + +/** + * This function sets the callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Calling MQTTClient_setCallbacks() puts the + * client into multi-threaded mode. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. See @ref async for more information. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTClient_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTClient_messageArrived() callback + * function. This callback function must be set when you call + * MQTTClient_setCallbacks(), as otherwise there would be nowhere to deliver + * any incoming messages. + * @param dc A pointer to an MQTTClient_deliveryComplete() callback + * function. You can set this to NULL if your application publishes + * synchronously or if you do not want to check for successful delivery. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl, + MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc); + + +/** + * This is a callback function, which will be called when the a disconnect + * packet is received from the server. This applies to MQTT V5 and above only. + * @param context A pointer to the context value originally passed to + * ::MQTTClient_setDisconnected(), which contains any application-specific context. + * @param properties The MQTT V5 properties received with the disconnect, if any. + * @param reasonCode The MQTT V5 reason code received with the disconnect. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTClient_disconnected() callback function for a client. This will be called + * if a disconnect packet is received from the server. Only valid for MQTT V5 and above. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTClient_disconnected() callback + * function. NULL removes the callback setting. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setDisconnected(MQTTClient handle, void* context, MQTTClient_disconnected* co); + +/** + * This is a callback function, the MQTT V5 version of MQTTClient_deliveryComplete(). + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the completed delivery of messages. + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note: It is not called when messages are published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + * @param packet_type the last received packet type for this completion. For QoS 1 + * always PUBACK. For QoS 2 could be PUBREC or PUBCOMP. + * @param properties the MQTT V5 properties returned with the last packet from the server + * @param reasonCode the reason code returned from the server + */ +typedef void MQTTClient_published(void* context, int dt, int packet_type, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +LIBMQTT_API int MQTTClient_setPublished(MQTTClient handle, void* context, MQTTClient_published* co); + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTClient_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; +} MQTTClient_createOptions; + +#define MQTTClient_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, MQTTVERSION_DEFAULT } + +/** + * A version of :MQTTClient_create() with additional options. + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp or ssl. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @param options additional options for the create. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_createWithOptions(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTClient_createOptions* options); + +/** + * MQTTClient_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTClient_willOptions + * structure is passed in the MQTTClient_connectOptions structure used in the + * MQTTClient_connect() call that connects the client to the server. The pointer + * to MQTTClient_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 means there is no binary payload option + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload in string form. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTClient_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTClient_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTClient_willOptions; + +#define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTClient_SSLOptions; + +#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** + * MQTTClient_libraryInfo is used to store details relating to the currently used + * library such as the version in use, the time it was built and relevant openSSL + * options. + * There is one static instance of this struct in MQTTClient.c + */ + +typedef struct +{ + const char* name; + const char* value; +} MQTTClient_nameValue; + +/** + * This function returns version information about the library. + * no trace information will be returned. + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTClient_nameValue* MQTTClient_getVersionInfo(void); + +/** + * MQTTClient_connectOptions defines several settings that control the way the + * client connects to an MQTT server. + * + * Note: Default values are not defined for members of + * MQTTClient_connectOptions so it is good practice to specify all settings. + * If the MQTTClient_connectOptions structure is defined as an automatic + * variable, all members are set to random values and thus must be set by the + * client application. If the MQTTClient_connectOptions structure is defined + * as a static variable, initialization (in compliant compilers) sets all + * values to 0 (NULL for pointers). A #keepAliveInterval setting of 0 prevents + * correct operation of the client and so you must at least set a value + * for #keepAliveInterval. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3, 4, 5, 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no returned values + * 4 signifies no binary password option + * 5 signifies no maxInflightMessages and cleanstart + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTClient_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This is a boolean value that controls how many messages can be in-flight + * simultaneously. Setting reliable to true means that a published + * message must be completed (acknowledgements received) before another + * can be sent. Attempts to publish additional messages receive an + * ::MQTTCLIENT_MAX_MESSAGES_INFLIGHT return code. Setting this flag to + * false allows up to 10 messages to be in-flight. This can increase + * overall throughput in some circumstances. + */ + int reliable; + /** + * This is a pointer to an MQTTClient_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTClient_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTClient_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTClient_SSLOptions* ssl; + /** + * The number of entries in the optional serverURIs array. Defaults to 0. + */ + int serverURIcount; + /** + * An optional array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * If this list is empty (the default), the server URI specified on MQTTClient_create() + * is used. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + * MQTTVERSION_5 (5) = only try version 5.0 + */ + int MQTTVersion; + /** + * Returned from the connect when the MQTT version used to connect is 3.1.1 + */ + struct + { + const char* serverURI; /**< the serverURI connected to */ + int MQTTVersion; /**< the MQTT version used to connect with */ + int sessionPresent; /**< if the MQTT version is 3.1.1, the value of sessionPresent returned in the connack */ + } returned; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct + { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /** + * The maximum number of messages in flight + */ + int maxInflightMessages; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * HTTP headers for websockets + */ + const MQTTClient_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTClient_connectOptions; + +#define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +/** + * This function attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @return ::MQTTCLIENT_SUCCESS if the client successfully connects to the + * server. An error code is returned if the client was unable to connect to + * the server. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options); + +/** MQTT version 5.0 response information */ +typedef struct MQTTResponse +{ + int version; /* the version number of this structure */ + enum MQTTReasonCodes reasonCode; /* the MQTT 5.0 reason code returned */ + int reasonCodeCount; /* the number of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + enum MQTTReasonCodes* reasonCodes; /* a list of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + MQTTProperties* properties; /* optionally, the MQTT 5.0 properties returned */ +} MQTTResponse; + +#define MQTTResponse_initializer {1, MQTTREASONCODE_SUCCESS, 0, NULL, NULL} + +/** + * Frees the storage associated with the MQTT response. + * @param response the response structure to be freed + */ +LIBMQTT_API void MQTTResponse_free(MQTTResponse response); + +/** + * Attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using MQTT version 5.0 and the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @param connectProperties the MQTT 5.0 connect properties to use + * @param willProperties the MQTT 5.0 properties to set on the will message + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_connect5(MQTTClient handle, MQTTClient_connectOptions* options, + MQTTProperties* connectProperties, MQTTProperties* willProperties); + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTClient_connectOptions.cleansession and MQTTClient_connect()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param timeout The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTClient_disconnect(MQTTClient handle, int timeout); + +LIBMQTT_API int MQTTClient_disconnect5(MQTTClient handle, int timeout, enum MQTTReasonCodes reason, MQTTProperties* props); + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTClient_isConnected(MQTTClient handle); + + +/* Subscribe is synchronous. QoS list parameter is changed on return to granted QoSs. + Returns return code, MQTTCLIENT_SUCCESS == success, non-zero some sort of error (TBD) */ + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTClient_subscribe(MQTTClient handle, const char* topic, int qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribe5(MQTTClient handle, const char* topic, int qos, + MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribeMany5(MQTTClient handle, int count, char* const* topic, + int* qos, MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @return ::MQTTCLIENT_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTClient_unsubscribe(MQTTClient handle, const char* topic); + +/** + * This function attempts to remove an existing subscription made by the + * specified client using MQTT 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribe5(MQTTClient handle, const char* topic, MQTTProperties* props); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @return ::MQTTCLIENT_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client using MQTT version 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribeMany5(MQTTClient handle, int count, char* const* topic, MQTTProperties* props); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publishMessage()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publish(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, int qos, int retained, + MQTTClient_deliveryToken* dt); + +/** + * Attempts to publish a message to a given topic using MQTT version 5.0 (see also + * MQTTClient_publishMessage5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param properties the MQTT 5.0 properties to be used + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publish5(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, + int qos, int retained, MQTTProperties* properties, MQTTClient_deliveryToken* dt); +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publishMessage(MQTTClient handle, const char* topicName, MQTTClient_message* msg, MQTTClient_deliveryToken* dt); + + +/** + * Attempts to publish a message to the given topic using MQTT version 5.0 + * (see also + * MQTTClient_publish5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char* topicName, MQTTClient_message* msg, + MQTTClient_deliveryToken* dt); + +/** + * This function is called by the client application to synchronize execution + * of the main thread with completed publication of a message. When called, + * MQTTClient_waitForCompletion() blocks execution until the message has been + * successful delivered or the specified timeout has expired. See @ref async. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param dt The ::MQTTClient_deliveryToken that represents the message being + * tested for successful delivery. Delivery tokens are issued by the + * publishing functions MQTTClient_publish() and MQTTClient_publishMessage(). + * @param timeout The maximum time to wait in milliseconds. + * @return ::MQTTCLIENT_SUCCESS if the message was successfully delivered. + * An error code is returned if the timeout expires or there was a problem + * checking the token. + */ +LIBMQTT_API int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken dt, unsigned long timeout); + + +/** + * This function sets a pointer to an array of delivery tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param tokens The address of a pointer to an ::MQTTClient_deliveryToken. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTCLIENT_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTClient_getPendingDeliveryTokens(MQTTClient handle, MQTTClient_deliveryToken **tokens); + +/** + * When implementing a single-threaded client, call this function periodically + * to allow processing of message retries and to send MQTT keepalive pings. + * If the application is calling MQTTClient_receive() regularly, then it is + * not necessary to call this function. + */ +LIBMQTT_API void MQTTClient_yield(void); + +/** + * This function performs a synchronous receive of incoming messages. It should + * be used only when the client application has not set callback methods to + * support asynchronous receipt of messages (see @ref async and + * MQTTClient_setCallbacks()). Using this function allows a single-threaded + * client subscriber application to be written. When called, this function + * blocks until the next message arrives or the specified timeout expires + *(see also MQTTClient_yield()). + * + * Important note: The application must free() the memory allocated + * to the topic and the message when processing is complete (see + * MQTTClient_freeMessage()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The address of a pointer to a topic. This function + * allocates the memory for the topic and returns it to the application + * by setting topicName to point to the topic. + * @param topicLen The length of the topic. If the return code from this + * function is ::MQTTCLIENT_TOPICNAME_TRUNCATED, the topic contains embedded + * NULL characters and the full topic should be retrieved by using + * topicLen. + * @param message The address of a pointer to the received message. This + * function allocates the memory for the message and returns it to the + * application by setting message to point to the received message. + * The pointer is set to NULL if the timeout expires. + * @param timeout The length of time to wait for a message in milliseconds. + * @return ::MQTTCLIENT_SUCCESS or ::MQTTCLIENT_TOPICNAME_TRUNCATED if a + * message is received. ::MQTTCLIENT_SUCCESS can also indicate that the + * timeout expired, in which case message is NULL. An error code is + * returned if there was a problem trying to receive a message. + */ +LIBMQTT_API int MQTTClient_receive(MQTTClient handle, char** topicName, int* topicLen, MQTTClient_message** message, + unsigned long timeout); + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTClient_free() library function. + * @param msg The address of a pointer to the ::MQTTClient_message structure + * to be freed. + */ +LIBMQTT_API void MQTTClient_freeMessage(MQTTClient_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client libary and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTClient_free(void* ptr); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTClient_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTClient + * structure to be freed. + */ +LIBMQTT_API void MQTTClient_destroy(MQTTClient* handle); + + +enum MQTTCLIENT_TRACE_LEVELS +{ + MQTTCLIENT_TRACE_MAXIMUM = 1, + MQTTCLIENT_TRACE_MEDIUM, + MQTTCLIENT_TRACE_MINIMUM, + MQTTCLIENT_TRACE_PROTOCOL, + MQTTCLIENT_TRACE_ERROR, + MQTTCLIENT_TRACE_SEVERE, + MQTTCLIENT_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTClient_setTraceLevel(enum MQTTCLIENT_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTClient_traceCallback(enum MQTTCLIENT_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTClient_setTraceCallback(MQTTClient_traceCallback* callback); + +/** + * Sets the timeout value for un/subscribe commands when waiting for the un/suback response from + * the server. Values less than 5000 are not allowed. + * @param handle A valid client handle from a successful call to MQTTClient_create(). + * @param milliSeconds the maximum number of milliseconds to wait + * @return MQTTCLIENT_SUCCESS or MQTTCLIENT_FAILURE + */ +LIBMQTT_API int MQTTClient_setCommandTimeout(MQTTClient handle, unsigned long milliSeconds); + +/** + * Returns a pointer to the string representation of the error or NULL. + * + * Do not free after use. Returns NULL if the error code is unknown. + */ +LIBMQTT_API const char* MQTTClient_strerror(int code); + +#if defined(__cplusplus) + } +#endif + +#endif + +/*! + * @cond MQTTClient_main + * @page async Asynchronous vs synchronous client applications + * This client library supports two modes of operation. These are referred to + * as synchronous and asynchronous modes. If your application + * calls MQTTClient_setCallbacks(), this puts the client into asynchronous + * mode, otherwise it operates in synchronous mode. + * + * In synchronous mode, the client application runs on a single thread. + * Messages are published using the MQTTClient_publish() and + * MQTTClient_publishMessage() functions. To determine that a QoS1 or QoS2 + * (see @ref qos) message has been successfully delivered, the application + * must call the MQTTClient_waitForCompletion() function. An example showing + * synchronous publication is shown in @ref pubsync. Receiving messages in + * synchronous mode uses the MQTTClient_receive() function. Client applications + * must call either MQTTClient_receive() or MQTTClient_yield() relatively + * frequently in order to allow processing of acknowledgements and the MQTT + * "pings" that keep the network connection to the server alive. + * + * In asynchronous mode, the client application runs on several threads. The + * main program calls functions in the client library to publish and subscribe, + * just as for the synchronous mode. Processing of handshaking and maintaining + * the network connection is performed in the background, however. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTClient_setCallbacks() (see MQTTClient_messageArrived(), + * MQTTClient_connectionLost() and MQTTClient_deliveryComplete()). + * This API is not thread safe however - it is not possible to call it from multiple + * threads without synchronization. You can use the MQTTAsync API for that. + * + * @page callbacks Callbacks + * You must not call a function from this API from within a callback otherwise + * a deadlock might result. The only exception to this is the ability to call + * connect within the connection lost callback, to allow a reconnect. + * + * When using MQTT 5.0, you can also call connect from within the disconnected + * callback, which is invoked when the MQTT server sends a disconnect packet. + * This server behaviour is allowed in MQTT 5.0, but not in MQTT 3.1.1, so the + * disconnected callback will never be invoked if you use MQTT 3.1.1. + * + * In particular, you must make a publish call within the message arrived callback. + * These restrictions are all lifted in the + * MQTTAsync API. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, or receive not called, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * It is up to the application to protect against this situation. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTClient_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTClient_subscribe() and MQTTClient_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page pubsync Synchronous publication example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for up to %d seconds for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID); + rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); + printf("Message with delivery token %d delivered\n", token); + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + printf("Failed to disconnect, return code %d\n", rc); + MQTTClient_destroy(&client); + return rc; +} + + * @endcode + * + * @page pubasync Asynchronous publication example +@code{.c} +#include +#include +#include +#include "MQTTClient.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + deliveredtoken = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (deliveredtoken != token) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } + +destroy_exit: + MQTTClient_destroy(&client); + +exit: + return rc; +} + + * @endcode + * @page subasync Asynchronous subscription example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +volatile MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + if ((rc = MQTTClient_subscribe(client, TOPIC, QOS)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to subscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + int ch; + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + if ((rc = MQTTClient_unsubscribe(client, TOPIC)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to unsubscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } +destroy_exit: + MQTTClient_destroy(&client); +exit: + return rc; +} + + * @endcode + * @page tracing Tracing + * + * Runtime tracing is controlled by environment variables. + * + * Tracing is switched on by setting MQTT_C_CLIENT_TRACE. A value of ON, or stdout, prints to + * stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTClientPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTClientPersistence.h new file mode 100644 index 0000000..d3caae4 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTClientPersistence.h @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** + * @file + * \brief This structure represents a persistent data store, used to store + * outbound and inbound messages, in order to achieve reliable messaging. + * + * The MQTT Client persists QoS1 and QoS2 messages in order to meet the + * assurances of delivery associated with these @ref qos levels. The messages + * are saved in persistent storage + * The type and context of the persistence implementation are specified when + * the MQTT client is created (see MQTTClient_create()). The default + * persistence type (::MQTTCLIENT_PERSISTENCE_DEFAULT) uses a file system-based + * persistence mechanism. The persistence_context argument passed to + * MQTTClient_create() when using the default peristence is a string + * representing the location of the persistence directory. If the context + * argument is NULL, the working directory will be used. + * + * To use memory-based persistence, an application passes + * ::MQTTCLIENT_PERSISTENCE_NONE as the persistence_type to + * MQTTClient_create(). This can lead to message loss in certain situations, + * but can be appropriate in some cases (see @ref qos). + * + * Client applications can provide their own persistence mechanism by passing + * ::MQTTCLIENT_PERSISTENCE_USER as the persistence_type. To implement a + * custom persistence mechanism, the application must pass an initialized + * ::MQTTClient_persistence structure as the persistence_context + * argument to MQTTClient_create(). + * + * If the functions defined return an ::MQTTCLIENT_PERSISTENCE_ERROR then the + * state of the persisted data should remain as it was prior to the function + * being called. For example, if Persistence_put() returns + * ::MQTTCLIENT_PERSISTENCE_ERROR, then it is assumed tha tthe persistent store + * does not contain the data that was passed to the function. Similarly, if + * Persistence_remove() returns ::MQTTCLIENT_PERSISTENCE_ERROR then it is + * assumed that the data to be removed is still held in the persistent store. + * + * It is up to the persistence implementation to log any error information that + * may be required to diagnose a persistence mechanism failure. + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENTPERSISTENCE_H) +#define MQTTCLIENTPERSISTENCE_H +/* +/// @endcond +*/ + +/** + * This persistence_type value specifies the default file system-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_DEFAULT 0 +/** + * This persistence_type value specifies a memory-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_NONE 1 +/** + * This persistence_type value specifies an application-specific + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_USER 2 + +/** + * Application-specific persistence functions must return this error code if + * there is a problem executing the function. + */ +#define MQTTCLIENT_PERSISTENCE_ERROR -2 + +/** + * @brief Initialize the persistent store. + * + * Either open the existing persistent store for this client ID or create a new + * one if one doesn't exist. If the persistent store is already open, return + * without taking any action. + * + * An application can use the same client identifier to connect to many + * different servers. The clientid in conjunction with the + * serverURI uniquely identifies the persistence store required. + * + * @param handle The address of a pointer to a handle for this persistence + * implementation. This function must set handle to a valid reference to the + * persistence following a successful return. + * The handle pointer is passed as an argument to all the other + * persistence functions. It may include the context parameter and/or any other + * data for use by the persistence functions. + * @param clientID The client identifier for which the persistent store should + * be opened. + * @param serverURI The connection string specified when the MQTT client was + * created (see MQTTClient_create()). + * @param context A pointer to any data required to initialize the persistent + * store (see ::MQTTClient_persistence). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_open)(void** handle, const char* clientID, const char* serverURI, void* context); + +/** + * @brief Close the persistent store referred to by the handle. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_close)(void* handle); + +/** + * @brief Put the specified data into the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string used as the key for the data to be put in the store. The + * key is later used to retrieve data from the store with Persistence_get(). + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers associated with + * this key. + * @param buflens An array of lengths of the data buffers. buflen[n] + * gives the length of buffer[n]. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_put)(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); + +/** + * @brief Retrieve the specified data from the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be retrieved. This is + * the same key used to save the data to the store with Persistence_put(). + * @param buffer The address of a pointer to a buffer. This function sets the + * pointer to point at the retrieved data, if successful. + * @param buflen The address of an int that is set to the length of + * buffer by this function if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_get)(void* handle, char* key, char** buffer, int* buflen); + +/** + * @brief Remove the data for the specified key from the store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be removed from the + * store. This is the same key used to save the data to the store with + * Persistence_put(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_remove)(void* handle, char* key); + +/** + * @brief Returns the keys in this persistent data store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param keys The address of a pointer to pointers to strings. Assuming + * successful execution, this function allocates memory to hold the returned + * keys (strings used to store the data with Persistence_put()). It also + * allocates memory to hold an array of pointers to these strings. keys + * is set to point to the array of pointers to strings. + * @param nkeys A pointer to the number of keys in this persistent data store. + * This function sets the number of keys, if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_keys)(void* handle, char*** keys, int* nkeys); + +/** + * @brief Clears the persistence store, so that it no longer contains any + * persisted data. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_clear)(void* handle); + +/** + * @brief Returns whether any data has been persisted using the specified key. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key The string to be tested for existence in the store. + * @return Return 0 if the key was found in the store, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_containskey)(void* handle, char* key); + +/** + * @brief A structure containing the function pointers to a persistence + * implementation and the context or state that will be shared across all + * the persistence functions. + */ +typedef struct { + /** + * A pointer to any data required to initialize the persistent store. + */ + void* context; + /** + * A function pointer to an implementation of Persistence_open(). + */ + Persistence_open popen; + /** + * A function pointer to an implementation of Persistence_close(). + */ + Persistence_close pclose; + /** + * A function pointer to an implementation of Persistence_put(). + */ + Persistence_put pput; + /** + * A function pointer to an implementation of Persistence_get(). + */ + Persistence_get pget; + /** + * A function pointer to an implementation of Persistence_remove(). + */ + Persistence_remove premove; + /** + * A function pointer to an implementation of Persistence_keys(). + */ + Persistence_keys pkeys; + /** + * A function pointer to an implementation of Persistence_clear(). + */ + Persistence_clear pclear; + /** + * A function pointer to an implementation of Persistence_containskey(). + */ + Persistence_containskey pcontainskey; +} MQTTClient_persistence; + + +/** + * A callback which is invoked just before a write to persistence. This can be + * used to transform the data, for instance to encrypt it. + * @param context The context as set in ::MQTTAsync_setBeforePersistenceWrite + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers. + * @param buflens An array of lengths of the data buffers. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_beforeWrite(void* context, int bufcount, char* buffers[], int buflens[]); + + +/** + * A callback which is invoked just after a read from persistence. This can be + * used to transform the data, for instance to decrypt it. + * @param context The context as set in ::MQTTAsync_setAfterPersistenceRead + * @param buffer The address of a pointer to a buffer. + * @param buflen The address of an int that is the length of the buffer. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_afterRead(void* context, char** buffer, int* buflen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTExportDeclarations.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTExportDeclarations.h new file mode 100644 index 0000000..d492ef1 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTExportDeclarations.h @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 Andreas Walter + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Andreas Walter - initially moved export declarations into separate fle + *******************************************************************************/ + +#if !defined(EXPORTDECLARATIONS_H) +#define EXPORTDECLARATIONS_H + +#if defined(_WIN32) || defined(_WIN64) +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __declspec(dllexport) +# elif defined(PAHO_MQTT_IMPORTS) +# define LIBMQTT_API __declspec(dllimport) +# else +# define LIBMQTT_API +# endif +#else +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __attribute__ ((visibility ("default"))) +# else +# define LIBMQTT_API extern +# endif +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPacket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPacket.h new file mode 100644 index 0000000..658404a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPacket.h @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - big endian Linux reversed definition + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKET_H) +#define MQTTPACKET_H + +#include "Socket.h" +#if defined(OPENSSL) +#include "SSLSocket.h" +#endif +#include "LinkedList.h" +#include "Clients.h" + +typedef unsigned int bool; +typedef void* (*pf)(int, unsigned char, char*, size_t); + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" + +enum errors +{ + MQTTPACKET_BAD = -4, + MQTTPACKET_BUFFER_TOO_SHORT = -2, + MQTTPACKET_READ_ERROR = -1, + MQTTPACKET_READ_COMPLETE +}; + + +enum msgTypes +{ + CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, + PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, + PINGREQ, PINGRESP, DISCONNECT, AUTH +}; + +#if defined(__linux__) +#include +#if __BYTE_ORDER == __BIG_ENDIAN + #define REVERSED 1 +#endif +#endif + +/** + * Bitfields for the MQTT header byte. + */ +typedef union +{ + /*unsigned*/ char byte; /**< the whole byte */ +#if defined(REVERSED) + struct + { + unsigned int type : 4; /**< message type nibble */ + bool dup : 1; /**< DUP flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool retain : 1; /**< retained flag bit */ + } bits; +#else + struct + { + bool retain : 1; /**< retained flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool dup : 1; /**< DUP flag bit */ + unsigned int type : 4; /**< message type nibble */ + } bits; +#endif +} Header; + + +/** + * Data for a connect packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connect flags */ +#if defined(REVERSED) + struct + { + bool username : 1; /**< 3.1 user name */ + bool password : 1; /**< 3.1 password */ + bool willRetain : 1; /**< will retain setting */ + unsigned int willQoS : 2; /**< will QoS value */ + bool will : 1; /**< will flag */ + bool cleanstart : 1; /**< cleansession flag */ + int : 1; /**< unused */ + } bits; +#else + struct + { + int : 1; /**< unused */ + bool cleanstart : 1; /**< cleansession flag */ + bool will : 1; /**< will flag */ + unsigned int willQoS : 2; /**< will QoS value */ + bool willRetain : 1; /**< will retain setting */ + bool password : 1; /**< 3.1 password */ + bool username : 1; /**< 3.1 user name */ + } bits; +#endif + } flags; /**< connect flags byte */ + + char *Protocol, /**< MQTT protocol name */ + *clientID, /**< string client id */ + *willTopic, /**< will topic */ + *willMsg; /**< will payload */ + + int keepAliveTimer; /**< keepalive timeout value in seconds */ + unsigned char version; /**< MQTT version number */ +} Connect; + + +/** + * Data for a connack packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connack flags */ +#if defined(REVERSED) + struct + { + unsigned int reserved : 7; /**< message type nibble */ + bool sessionPresent : 1; /**< was a session found on the server? */ + } bits; +#else + struct + { + bool sessionPresent : 1; /**< was a session found on the server? */ + unsigned int reserved : 7; /**< message type nibble */ + } bits; +#endif + } flags; /**< connack flags byte */ + unsigned char rc; /**< connack reason code */ + unsigned int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Connack; + + +/** + * Data for a packet with header only. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ +} MQTTPacket; + + +/** + * Data for a suback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* qoss; /**< list of granted QoSs (MQTT 3/4) / reason codes (MQTT 5) */ +} Suback; + + +/** + * Data for an MQTT V5 unsuback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* reasonCodes; /**< list of reason codes */ +} Unsuback; + + +/** + * Data for a publish packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + char* topic; /**< topic string */ + int topiclen; + int msgId; /**< MQTT message id */ + char* payload; /**< binary payload, length delimited */ + int payloadlen; /**< payload length */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + uint8_t mask[4]; /**< the websockets mask the payload is masked with, if any */ +} Publish; + + +/** + * Data for one of the ack packets. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + unsigned char rc; /**< MQTT 5 reason code */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Ack; + +typedef Ack Puback; +typedef Ack Pubrec; +typedef Ack Pubrel; +typedef Ack Pubcomp; + +int MQTTPacket_encode(char* buf, size_t length); +int MQTTPacket_decode(networkHandles* net, size_t* value); +int readInt(char** pptr); +char* readUTF(char** pptr, char* enddata); +unsigned char readChar(char** pptr); +void writeChar(char** pptr, char c); +void writeInt(char** pptr, int anInt); +void writeUTF(char** pptr, const char* string); +void writeData(char** pptr, const void* data, int datalen); + +const char* MQTTPacket_name(int ptype); + +void* MQTTPacket_Factory(int MQTTVersion, networkHandles* net, int* error); +int MQTTPacket_send(networkHandles* net, Header header, char* buffer, size_t buflen, int free, int MQTTVersion); +int MQTTPacket_sends(networkHandles* net, Header header, PacketBuffers* buffers, int MQTTVersion); + +void* MQTTPacket_header_only(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +int MQTTPacket_send_disconnect(Clients* client, enum MQTTReasonCodes reason, MQTTProperties* props); + +void* MQTTPacket_publish(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freePublish(Publish* pack); +int MQTTPacket_send_publish(Publish* pack, int dup, int qos, int retained, networkHandles* net, const char* clientID); +int MQTTPacket_send_puback(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +void MQTTPacket_freeAck(Ack* pack); +void MQTTPacket_freeSuback(Suback* pack); +void MQTTPacket_freeUnsuback(Unsuback* pack); +int MQTTPacket_send_pubrec(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubrel(int MQTTVersion, int msgid, int dup, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubcomp(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); + +void MQTTPacket_free_packet(MQTTPacket* pack); + +void writeInt4(char** pptr, int anInt); +int readInt4(char** pptr); +void writeMQTTLenString(char** pptr, MQTTLenString lenstring); +int MQTTLenStringRead(MQTTLenString* lenstring, char** pptr, char* enddata); +int MQTTPacket_VBIlen(int rem_len); +int MQTTPacket_decodeBuf(char* buf, unsigned int* value); + +#include "MQTTPacketOut.h" + +#endif /* MQTTPACKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPacketOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPacketOut.h new file mode 100644 index 0000000..d962554 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPacketOut.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKETOUT_H) +#define MQTTPACKETOUT_H + +#include "MQTTPacket.h" + +int MQTTPacket_send_connect(Clients* client, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +void* MQTTPacket_connack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freeConnack(Connack* pack); + +int MQTTPacket_send_pingreq(networkHandles* net, const char* clientID); + +int MQTTPacket_send_subscribe(List* topics, List* qoss, MQTTSubscribe_options* opts, MQTTProperties* props, + int msgid, int dup, Clients* client); +void* MQTTPacket_suback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +int MQTTPacket_send_unsubscribe(List* topics, MQTTProperties* props, int msgid, int dup, Clients* client); +void* MQTTPacket_unsuback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPersistence.h new file mode 100644 index 0000000..ed2e0ce --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPersistence.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - async client updates + * Ian Craggs - fix for bug 432903 - queue persistence + * Ian Craggs - MQTT V5 updates + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCE_H) +#define MQTTPERSISTENCE_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include "Clients.h" +#include "MQTTProperties.h" + +/** Stem of the key for a sent PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_PUBLISH_SENT "s-" +/** Stem of the key for a sent PUBREL */ +#define PERSISTENCE_PUBREL "sc-" +/** Stem of the key for a received PUBLISH QoS2 */ +#define PERSISTENCE_PUBLISH_RECEIVED "r-" + +/** Stem of the key for a sent MQTT V5 PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_V5_PUBLISH_SENT "s5-" +/** Stem of the key for a sent MQTT V5 PUBREL */ +#define PERSISTENCE_V5_PUBREL "sc5-" +/** Stem of the key for a received MQTT V5 PUBLISH QoS2 */ +#define PERSISTENCE_V5_PUBLISH_RECEIVED "r5-" + +/** Stem of the key for an async client command */ +#define PERSISTENCE_COMMAND_KEY "c-" +/** Stem of the key for an MQTT V5 async client command */ +#define PERSISTENCE_V5_COMMAND_KEY "c5-" +/** Stem of the key for an client incoming message queue */ +#define PERSISTENCE_QUEUE_KEY "q-" +/** Stem of the key for an MQTT V5 incoming message queue */ +#define PERSISTENCE_V5_QUEUE_KEY "q5-" +/** Maximum length of a stem for a persistence key */ +#define PERSISTENCE_MAX_STEM_LENGTH 3 +/** Maximum allowed length of a persistence key */ +#define PERSISTENCE_MAX_KEY_LENGTH 9 +/** Maximum size of an integer sequence number appended to a persistence key */ +#define PERSISTENCE_SEQNO_LIMIT 1000000 /*10^(PERSISTENCE_MAX_KEY_LENGTH - PERSISTENCE_MAX_STEM_LENGTH)*/ + +int MQTTPersistence_create(MQTTClient_persistence** per, int type, void* pcontext); +int MQTTPersistence_initialize(Clients* c, const char* serverURI); +int MQTTPersistence_close(Clients* c); +int MQTTPersistence_clear(Clients* c); +int MQTTPersistence_restorePackets(Clients* c); +void* MQTTPersistence_restorePacket(int MQTTVersion, char* buffer, size_t buflen); +void MQTTPersistence_insertInOrder(List* list, void* content, size_t size); +int MQTTPersistence_putPacket(int socket, char* buf0, size_t buf0len, int count, + char** buffers, size_t* buflens, int htype, int msgId, int scr, int MQTTVersion); +int MQTTPersistence_remove(Clients* c, char* type, int qos, int msgId); +void MQTTPersistence_wrapMsgID(Clients *c); + +typedef struct +{ + char struct_id[4]; + int struct_version; + int payloadlen; + void* payload; + int qos; + int retained; + int dup; + int msgid; + MQTTProperties properties; +} MQTTPersistence_message; + +typedef struct +{ + MQTTPersistence_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} MQTTPersistence_qEntry; + +int MQTTPersistence_unpersistQueueEntry(Clients* client, MQTTPersistence_qEntry* qe); +int MQTTPersistence_persistQueueEntry(Clients* aclient, MQTTPersistence_qEntry* qe); +int MQTTPersistence_restoreMessageQueue(Clients* c); +#ifdef __cplusplus + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPersistenceDefault.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPersistenceDefault.h new file mode 100644 index 0000000..506b4da --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTPersistenceDefault.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCEDEFAULT_H) +#define MQTTPERSISTENCEDEFAULT_H + +/** 8.3 filesystem */ +#define MESSAGE_FILENAME_LENGTH 8 +/** Extension of the filename */ +#define MESSAGE_FILENAME_EXTENSION ".msg" + +/* prototypes of the functions for the default file system persistence */ +int pstopen(void** handle, const char* clientID, const char* serverURI, void* context); +int pstclose(void* handle); +int pstput(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); +int pstget(void* handle, char* key, char** buffer, int* buflen); +int pstremove(void* handle, char* key); +int pstkeys(void* handle, char*** keys, int* nkeys); +int pstclear(void* handle); +int pstcontainskey(void* handle, char* key); + +int pstmkdir(char *pPathname); + +#endif + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProperties.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProperties.h new file mode 100644 index 0000000..81b8e3a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProperties.h @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPROPERTIES_H) +#define MQTTPROPERTIES_H + +#include "MQTTExportDeclarations.h" + +#define MQTT_INVALID_PROPERTY_ID -2 + +/** The one byte MQTT V5 property indicator */ +enum MQTTPropertyCodes { + MQTTPROPERTY_CODE_PAYLOAD_FORMAT_INDICATOR = 1, /**< The value is 1 */ + MQTTPROPERTY_CODE_MESSAGE_EXPIRY_INTERVAL = 2, /**< The value is 2 */ + MQTTPROPERTY_CODE_CONTENT_TYPE = 3, /**< The value is 3 */ + MQTTPROPERTY_CODE_RESPONSE_TOPIC = 8, /**< The value is 8 */ + MQTTPROPERTY_CODE_CORRELATION_DATA = 9, /**< The value is 9 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIER = 11, /**< The value is 11 */ + MQTTPROPERTY_CODE_SESSION_EXPIRY_INTERVAL = 17, /**< The value is 17 */ + MQTTPROPERTY_CODE_ASSIGNED_CLIENT_IDENTIFER = 18,/**< The value is 18 */ + MQTTPROPERTY_CODE_SERVER_KEEP_ALIVE = 19, /**< The value is 19 */ + MQTTPROPERTY_CODE_AUTHENTICATION_METHOD = 21, /**< The value is 21 */ + MQTTPROPERTY_CODE_AUTHENTICATION_DATA = 22, /**< The value is 22 */ + MQTTPROPERTY_CODE_REQUEST_PROBLEM_INFORMATION = 23,/**< The value is 23 */ + MQTTPROPERTY_CODE_WILL_DELAY_INTERVAL = 24, /**< The value is 24 */ + MQTTPROPERTY_CODE_REQUEST_RESPONSE_INFORMATION = 25,/**< The value is 25 */ + MQTTPROPERTY_CODE_RESPONSE_INFORMATION = 26, /**< The value is 26 */ + MQTTPROPERTY_CODE_SERVER_REFERENCE = 28, /**< The value is 28 */ + MQTTPROPERTY_CODE_REASON_STRING = 31, /**< The value is 31 */ + MQTTPROPERTY_CODE_RECEIVE_MAXIMUM = 33, /**< The value is 33*/ + MQTTPROPERTY_CODE_TOPIC_ALIAS_MAXIMUM = 34, /**< The value is 34 */ + MQTTPROPERTY_CODE_TOPIC_ALIAS = 35, /**< The value is 35 */ + MQTTPROPERTY_CODE_MAXIMUM_QOS = 36, /**< The value is 36 */ + MQTTPROPERTY_CODE_RETAIN_AVAILABLE = 37, /**< The value is 37 */ + MQTTPROPERTY_CODE_USER_PROPERTY = 38, /**< The value is 38 */ + MQTTPROPERTY_CODE_MAXIMUM_PACKET_SIZE = 39, /**< The value is 39 */ + MQTTPROPERTY_CODE_WILDCARD_SUBSCRIPTION_AVAILABLE = 40,/**< The value is 40 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIERS_AVAILABLE = 41,/**< The value is 41 */ + MQTTPROPERTY_CODE_SHARED_SUBSCRIPTION_AVAILABLE = 42/**< The value is 241 */ +}; + +/** + * Returns a printable string description of an MQTT V5 property code. + * @param value an MQTT V5 property code. + * @return the printable string description of the input property code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTPropertyName(enum MQTTPropertyCodes value); + +/** The one byte MQTT V5 property type */ +enum MQTTPropertyTypes { + MQTTPROPERTY_TYPE_BYTE, + MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER, + MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER, + MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER, + MQTTPROPERTY_TYPE_BINARY_DATA, + MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING, + MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR +}; + +/** + * Returns the MQTT V5 type code of an MQTT V5 property. + * @param value an MQTT V5 property code. + * @return the MQTT V5 type code of the input property. -1 if the code was not found. + */ +LIBMQTT_API int MQTTProperty_getType(enum MQTTPropertyCodes value); + +/** + * The data for a length delimited string + */ +typedef struct +{ + int len; /**< the length of the string */ + char* data; /**< pointer to the string data */ +} MQTTLenString; + + +/** + * Structure to hold an MQTT version 5 property of any type + */ +typedef struct +{ + enum MQTTPropertyCodes identifier; /**< The MQTT V5 property id. A multi-byte integer. */ + /** The value of the property, as a union of the different possible types. */ + union { + unsigned char byte; /**< holds the value of a byte property type */ + unsigned short integer2; /**< holds the value of a 2 byte integer property type */ + unsigned int integer4; /**< holds the value of a 4 byte integer property type */ + struct { + MQTTLenString data; /**< The value of a string property, or the name of a user property. */ + MQTTLenString value; /**< The value of a user property. */ + }; + } value; +} MQTTProperty; + +/** + * MQTT version 5 property list + */ +typedef struct MQTTProperties +{ + int count; /**< number of property entries in the array */ + int max_count; /**< max number of properties that the currently allocated array can store */ + int length; /**< mbi: byte length of all properties */ + MQTTProperty *array; /**< array of properties */ +} MQTTProperties; + +#define MQTTProperties_initializer {0, 0, 0, NULL} + +/** + * Returns the length of the properties structure when serialized ready for network transmission. + * @param props an MQTT V5 property structure. + * @return the length in bytes of the properties when serialized. + */ +int MQTTProperties_len(MQTTProperties* props); + +/** + * Add a property pointer to the property array. There is no memory allocation. + * @param props The property list to add the property to. + * @param prop The property to add to the list. + * @return 0 on success, -1 on failure. + */ +LIBMQTT_API int MQTTProperties_add(MQTTProperties* props, const MQTTProperty* prop); + +/** + * Serialize the given property list to a character buffer, e.g. for writing to the network. + * @param pptr pointer to the buffer - move the pointer as we add data + * @param properties pointer to the property list, can be NULL + * @return whether the write succeeded or not: number of bytes written, or < 0 on failure. + */ +int MQTTProperties_write(char** pptr, const MQTTProperties* properties); + +/** + * Reads a property list from a character buffer into an array. + * @param properties pointer to the property list to be filled. Should be initalized but empty. + * @param pptr pointer to the character buffer. + * @param enddata pointer to the end of the character buffer so we don't read beyond. + * @return 1 if the properties were read successfully. + */ +int MQTTProperties_read(MQTTProperties* properties, char** pptr, char* enddata); + +/** + * Free all memory allocated to the property list, including any to individual properties. + * @param properties pointer to the property list. + */ +LIBMQTT_API void MQTTProperties_free(MQTTProperties* properties); + +/** + * Copy the contents of a property list, allocating additional memory if needed. + * @param props pointer to the property list. + * @return the duplicated property list. + */ +LIBMQTT_API MQTTProperties MQTTProperties_copy(const MQTTProperties* props); + +/** + * Checks if property list contains a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return 1 if found, 0 if not. + */ +LIBMQTT_API int MQTTProperties_hasProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the number of instances of a property id. Most properties can exist only once. + * User properties and subscription ids can exist more than once. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the number of times found. Can be 0. + */ +LIBMQTT_API int MQTTProperties_propertyCount(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property. The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValue(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property when it's not the only instance. + * The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValueAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +/** + * Returns a pointer to the property structure for a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns a pointer to the property structure for a specific property when it's not the only instance. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getPropertyAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +#endif /* MQTTPROPERTIES_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProtocol.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProtocol.h new file mode 100644 index 0000000..52bcd15 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProtocol.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - MQTT 3.1.1 updates + *******************************************************************************/ + +#if !defined(MQTTPROTOCOL_H) +#define MQTTPROTOCOL_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +typedef struct +{ + int socket; + Publications* p; +} pending_write; + + +typedef struct +{ + List publications; + unsigned int msgs_received; + unsigned int msgs_sent; + List pending_writes; /* for qos 0 writes not complete */ +} MQTTProtocol; + + +#include "MQTTProtocolOut.h" + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProtocolClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProtocolClient.h new file mode 100644 index 0000000..2d077af --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProtocolClient.h @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 updates + * Rong Xiang, Ian Craggs - C++ compatibility + * Ian Craggs - add debug definition of MQTTStrdup for when needed + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLCLIENT_H) +#define MQTTPROTOCOLCLIENT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Log.h" +#include "MQTTProtocol.h" +#include "Messages.h" +#include "MQTTProperties.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +int MQTTProtocol_startPublish(Clients* pubclient, Publish* publish, int qos, int retained, Messages** m); +Messages* MQTTProtocol_createMessage(Publish* publish, Messages** mm, int qos, int retained, int allocatePayload); +Publications* MQTTProtocol_storePublication(Publish* publish, int* len); +int messageIDCompare(void* a, void* b); +int MQTTProtocol_assignMsgId(Clients* client); +void MQTTProtocol_removePublication(Publications* p); +void Protocol_processPublication(Publish* publish, Clients* client, int allocatePayload); + +int MQTTProtocol_handlePublishes(void* pack, int sock); +int MQTTProtocol_handlePubacks(void* pack, int sock); +int MQTTProtocol_handlePubrecs(void* pack, int sock); +int MQTTProtocol_handlePubrels(void* pack, int sock); +int MQTTProtocol_handlePubcomps(void* pack, int sock); + +void MQTTProtocol_closeSession(Clients* c, int sendwill); +void MQTTProtocol_keepalive(START_TIME_TYPE); +void MQTTProtocol_retry(START_TIME_TYPE, int, int); +void MQTTProtocol_freeClient(Clients* client); +void MQTTProtocol_emptyMessageList(List* msgList); +void MQTTProtocol_freeMessageList(List* msgList); + +char* MQTTStrncpy(char *dest, const char* src, size_t num); +char* MQTTStrdup(const char* src); + +//#define MQTTStrdup(src) MQTTStrncpy(malloc(strlen(src)+1), src, strlen(src)+1) + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProtocolOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProtocolOut.h new file mode 100644 index 0000000..6a50155 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTProtocolOut.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - SNI support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLOUT_H) +#define MQTTPROTOCOLOUT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" +#include "Log.h" +#include "Messages.h" +#include "MQTTProtocol.h" +#include "MQTTProtocolClient.h" + +#define MQTT_DEFAULT_PORT 1883 +#define SECURE_MQTT_DEFAULT_PORT 8883 +#define WS_DEFAULT_PORT 80 + +size_t MQTTProtocol_addressPort(const char* uri, int* port, const char **topic, int default_port); +void MQTTProtocol_reconnect(const char* ip_address, Clients* client); +#if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#else +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#endif +int MQTTProtocol_handlePingresps(void* pack, int sock); +int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, int msgID, + MQTTSubscribe_options* opts, MQTTProperties* props); +int MQTTProtocol_handleSubacks(void* pack, int sock); +int MQTTProtocol_unsubscribe(Clients* client, List* topics, int msgID, MQTTProperties* props); +int MQTTProtocol_handleUnsubacks(void* pack, int sock); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTReasonCodes.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTReasonCodes.h new file mode 100644 index 0000000..2dc08ea --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTReasonCodes.h @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTREASONCODES_H) +#define MQTTREASONCODES_H + +#include "MQTTExportDeclarations.h" + +/** The MQTT V5 one byte reason code */ +enum MQTTReasonCodes { + MQTTREASONCODE_SUCCESS = 0, + MQTTREASONCODE_NORMAL_DISCONNECTION = 0, + MQTTREASONCODE_GRANTED_QOS_0 = 0, + MQTTREASONCODE_GRANTED_QOS_1 = 1, + MQTTREASONCODE_GRANTED_QOS_2 = 2, + MQTTREASONCODE_DISCONNECT_WITH_WILL_MESSAGE = 4, + MQTTREASONCODE_NO_MATCHING_SUBSCRIBERS = 16, + MQTTREASONCODE_NO_SUBSCRIPTION_FOUND = 17, + MQTTREASONCODE_CONTINUE_AUTHENTICATION = 24, + MQTTREASONCODE_RE_AUTHENTICATE = 25, + MQTTREASONCODE_UNSPECIFIED_ERROR = 128, + MQTTREASONCODE_MALFORMED_PACKET = 129, + MQTTREASONCODE_PROTOCOL_ERROR = 130, + MQTTREASONCODE_IMPLEMENTATION_SPECIFIC_ERROR = 131, + MQTTREASONCODE_UNSUPPORTED_PROTOCOL_VERSION = 132, + MQTTREASONCODE_CLIENT_IDENTIFIER_NOT_VALID = 133, + MQTTREASONCODE_BAD_USER_NAME_OR_PASSWORD = 134, + MQTTREASONCODE_NOT_AUTHORIZED = 135, + MQTTREASONCODE_SERVER_UNAVAILABLE = 136, + MQTTREASONCODE_SERVER_BUSY = 137, + MQTTREASONCODE_BANNED = 138, + MQTTREASONCODE_SERVER_SHUTTING_DOWN = 139, + MQTTREASONCODE_BAD_AUTHENTICATION_METHOD = 140, + MQTTREASONCODE_KEEP_ALIVE_TIMEOUT = 141, + MQTTREASONCODE_SESSION_TAKEN_OVER = 142, + MQTTREASONCODE_TOPIC_FILTER_INVALID = 143, + MQTTREASONCODE_TOPIC_NAME_INVALID = 144, + MQTTREASONCODE_PACKET_IDENTIFIER_IN_USE = 145, + MQTTREASONCODE_PACKET_IDENTIFIER_NOT_FOUND = 146, + MQTTREASONCODE_RECEIVE_MAXIMUM_EXCEEDED = 147, + MQTTREASONCODE_TOPIC_ALIAS_INVALID = 148, + MQTTREASONCODE_PACKET_TOO_LARGE = 149, + MQTTREASONCODE_MESSAGE_RATE_TOO_HIGH = 150, + MQTTREASONCODE_QUOTA_EXCEEDED = 151, + MQTTREASONCODE_ADMINISTRATIVE_ACTION = 152, + MQTTREASONCODE_PAYLOAD_FORMAT_INVALID = 153, + MQTTREASONCODE_RETAIN_NOT_SUPPORTED = 154, + MQTTREASONCODE_QOS_NOT_SUPPORTED = 155, + MQTTREASONCODE_USE_ANOTHER_SERVER = 156, + MQTTREASONCODE_SERVER_MOVED = 157, + MQTTREASONCODE_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158, + MQTTREASONCODE_CONNECTION_RATE_EXCEEDED = 159, + MQTTREASONCODE_MAXIMUM_CONNECT_TIME = 160, + MQTTREASONCODE_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161, + MQTTREASONCODE_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162 +}; + +/** + * Returns a printable string description of an MQTT V5 reason code. + * @param value an MQTT V5 reason code. + * @return the printable string description of the input reason code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTReasonCode_toString(enum MQTTReasonCodes value); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTSubscribeOpts.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTSubscribeOpts.h new file mode 100644 index 0000000..264e4d0 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTSubscribeOpts.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(SUBOPTS_H) +#define SUBOPTS_H + +/** The MQTT V5 subscribe options, apart from QoS which existed before V5. */ +typedef struct MQTTSubscribe_options +{ + /** The eyecatcher for this structure. Must be MQSO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0. + */ + int struct_version; + /** To not receive our own publications, set to 1. + * 0 is the original MQTT behaviour - all messages matching the subscription are received. + */ + unsigned char noLocal; + /** To keep the retain flag as on the original publish message, set to 1. + * If 0, defaults to the original MQTT behaviour where the retain flag is only set on + * publications sent by a broker if in response to a subscribe request. + */ + unsigned char retainAsPublished; + /** 0 - send retained messages at the time of the subscribe (original MQTT behaviour) + * 1 - send retained messages on subscribe only if the subscription is new + * 2 - do not send retained messages at all + */ + unsigned char retainHandling; +} MQTTSubscribe_options; + +#define MQTTSubscribe_options_initializer { {'M', 'Q', 'S', 'O'}, 0, 0, 0, 0 } + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTTime.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTTime.h new file mode 100644 index 0000000..8bd6860 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/MQTTTime.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + *******************************************************************************/ + +#if !defined(MQTTTIME_H) +#define MQTTTIME_H + +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#if WINVER >= _WIN32_WINNT_VISTA +#define START_TIME_TYPE ULONGLONG +#define START_TIME_ZERO 0 +#else +#define START_TIME_TYPE DWORD +#define START_TIME_ZERO 0 +#endif +#elif defined(AIX) +#define START_TIME_TYPE struct timespec +#define START_TIME_ZERO {0, 0} +#else +#include +#define START_TIME_TYPE struct timeval +#define START_TIME_ZERO {0, 0} +#endif + +#define ELAPSED_TIME_TYPE uint64_t +#define DIFF_TIME_TYPE int64_t + +void MQTTTime_sleep(ELAPSED_TIME_TYPE milliseconds); +START_TIME_TYPE MQTTTime_start_clock(void); +START_TIME_TYPE MQTTTime_now(void); +ELAPSED_TIME_TYPE MQTTTime_elapsed(START_TIME_TYPE milliseconds); +DIFF_TIME_TYPE MQTTTime_difftime(START_TIME_TYPE new, START_TIME_TYPE old); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Messages.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Messages.h new file mode 100644 index 0000000..58f5eae --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Messages.h @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MESSAGES_H) +#define MESSAGES_H + +#include "Log.h" + +const char* Messages_get(int, enum LOG_LEVELS); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/OsWrapper.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/OsWrapper.h new file mode 100644 index 0000000..96b629d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/OsWrapper.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016, 2017 logi.cals GmbH + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Gunter Raidl - timer support for VxWorks + * Rainer Poisel - reusability + *******************************************************************************/ + +#if !defined(OSWRAPPER_H) +#define OSWRAPPER_H + +#if defined(_WRS_KERNEL) +#include + +#define lstat stat + +typedef unsigned long useconds_t; +void usleep(useconds_t useconds); + +#define timersub(a, b, result) \ + do \ + { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) \ + { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000L; \ + } \ + } while (0) +#endif /* defined(_WRS_KERNEL) */ + +#endif /* OSWRAPPER_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/SHA1.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/SHA1.h new file mode 100644 index 0000000..3ae2f0a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/SHA1.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2018, 2019 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(SHA1_H) +#define SHA1_H + +#if defined(OPENSSL) +#include + +/** SHA-1 Digest Length */ +#define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH + +#else /* if defined(OPENSSL) */ + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +typedef struct SHA_CTX_S +{ + HCRYPTPROV hProv; + HCRYPTHASH hHash; +} SHA_CTX; +#else /* if defined(_WIN32) || defined(_WIN64) */ + +#include +typedef struct SHA_CTX_S { + uint32_t h[5]; + union { + uint32_t w[16]; + uint8_t buffer[64]; + }; + unsigned int size; + unsigned int total; +} SHA_CTX; +#endif /* else if defined(_WIN32) || defined(_WIN64) */ + +#include + +/** SHA-1 Digest Length (number of bytes in SHA1) */ +#define SHA1_DIGEST_LENGTH (160/8) + +/** + * Initializes the SHA1 hashing algorithm + * + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Update + * @see SHA1_Final + */ +int SHA1_Init(SHA_CTX *ctx); + +/** + * Updates a block to the SHA1 hash + * + * @param[in,out] ctx hashing context structure + * @param[in] data block of data to hash + * @param[in] len length of block to hash + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Update(SHA_CTX *ctx, const void *data, size_t len); + +/** + * Produce final SHA1 hash + * + * @param[out] md SHA1 hash produced (must be atleast + * @p SHA1_DIGEST_LENGTH in length) + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Final(unsigned char *md, SHA_CTX *ctx); + +#endif /* if defined(OPENSSL) */ +#endif /* SHA1_H */ + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/SSLSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/SSLSocket.h new file mode 100644 index 0000000..86273c8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/SSLSocket.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs, Allan Stockdill-Mander - initial implementation + * Ian Craggs - SNI support + * Ian Craggs - post connect checks and CApath + *******************************************************************************/ +#if !defined(SSLSOCKET_H) +#define SSLSOCKET_H + +#if defined(_WIN32) || defined(_WIN64) + #define ssl_mutex_type HANDLE +#else + #include + #include + #define ssl_mutex_type pthread_mutex_t +#endif + +#include +#include "SocketBuffer.h" +#include "Clients.h" + +#define URI_SSL "ssl://" + +/** if we should handle openssl initialization (bool_value == 1) or depend on it to be initalized externally (bool_value == 0) */ +void SSLSocket_handleOpensslInit(int bool_value); + +int SSLSocket_initialize(void); +void SSLSocket_terminate(void); +int SSLSocket_setSocketForSSL(networkHandles* net, MQTTClient_SSLOptions* opts, const char* hostname, size_t hostname_len); + +int SSLSocket_getch(SSL* ssl, int socket, char* c); +char *SSLSocket_getdata(SSL* ssl, int socket, size_t bytes, size_t* actual_len, int* rc); + +int SSLSocket_close(networkHandles* net); +int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +int SSLSocket_connect(SSL* ssl, int sock, const char* hostname, int verify, int (*cb)(const char *str, size_t len, void *u), void* u); + +int SSLSocket_getPendingRead(void); +int SSLSocket_continueWrite(pending_writes* pw); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Socket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Socket.h new file mode 100644 index 0000000..39a8158 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Socket.h @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + * Ian Craggs - async client updates + *******************************************************************************/ + +#if !defined(SOCKET_H) +#define SOCKET_H + +#include +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#include +#define MAXHOSTNAMELEN 256 +#if !defined(SSLSOCKET_H) +#undef EAGAIN +#define EAGAIN WSAEWOULDBLOCK +#undef EINTR +#define EINTR WSAEINTR +#undef EINPROGRESS +#define EINPROGRESS WSAEINPROGRESS +#undef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#undef ENOTCONN +#define ENOTCONN WSAENOTCONN +#undef ECONNRESET +#define ECONNRESET WSAECONNRESET +#undef ETIMEDOUT +#define ETIMEDOUT WAIT_TIMEOUT +#endif +#define ioctl ioctlsocket +#define socklen_t int +#else +#define INVALID_SOCKET SOCKET_ERROR +#include +#if !defined(_WRS_KERNEL) +#include +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define ULONG size_t +#endif + +#include "mutex_type.h" /* Needed for mutex_type */ + +/** socket operation completed successfully */ +#define TCPSOCKET_COMPLETE 0 +#if !defined(SOCKET_ERROR) + /** error in socket operation */ + #define SOCKET_ERROR -1 +#endif +/** must be the same as SOCKETBUFFER_INTERRUPTED */ +#define TCPSOCKET_INTERRUPTED -22 +#define SSL_FATAL -3 + +#if !defined(INET6_ADDRSTRLEN) +#define INET6_ADDRSTRLEN 46 /** only needed for gcc/cygwin on windows */ +#endif + + +#if !defined(max) +#define max(A,B) ( (A) > (B) ? (A):(B)) +#endif + +#include "LinkedList.h" + +/* + * Network write buffers for an MQTT packet + */ +typedef struct +{ + int count; /**> number of buffers/buflens/frees */ + char** buffers; /**> array of byte buffers */ + size_t* buflens; /**> array of lengths of buffers */ + int* frees; /**> array of flags indicating whether each buffer needs to be freed */ + uint8_t mask[4]; /**> websocket mask used to mask the buffer data, if any */ +} PacketBuffers; + + +/** + * Structure to hold all socket data for the module + */ +typedef struct +{ + fd_set rset, /**< socket read set (see select doc) */ + rset_saved; /**< saved socket read set */ + int maxfdp1; /**< max descriptor used +1 (again see select doc) */ + List* clientsds; /**< list of client socket descriptors */ + ListElement* cur_clientsds; /**< current client socket descriptor (iterator) */ + List* connect_pending; /**< list of sockets for which a connect is pending */ + List* write_pending; /**< list of sockets for which a write is pending */ + fd_set pending_wset; /**< socket pending write set for select */ +} Sockets; + + +void Socket_outInitialize(void); +void Socket_outTerminate(void); +int Socket_getReadySocket(int more_work, struct timeval *tp, mutex_type mutex, int* rc); +int Socket_getch(int socket, char* c); +char *Socket_getdata(int socket, size_t bytes, size_t* actual_len, int* rc); +int Socket_putdatas(int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +void Socket_close(int socket); +#if defined(__GNUC__) && defined(__linux__) +/* able to use GNU's getaddrinfo_a to make timeouts possible */ +int Socket_new(const char* addr, size_t addr_len, int port, int* socket, long timeout); +#else +int Socket_new(const char* addr, size_t addr_len, int port, int* socket); +#endif + +int Socket_noPendingWrites(int socket); +char* Socket_getpeer(int sock); + +void Socket_addPendingWrite(int socket); +void Socket_clearPendingWrite(int socket); + +typedef void Socket_writeComplete(int socket, int rc); +void Socket_setWriteCompleteCallback(Socket_writeComplete*); + +#endif /* SOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/SocketBuffer.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/SocketBuffer.h new file mode 100644 index 0000000..0fc7d6e --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/SocketBuffer.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + *******************************************************************************/ + +#if !defined(SOCKETBUFFER_H) +#define SOCKETBUFFER_H + +#if defined(_WIN32) || defined(_WIN64) +#include +#else +#include +#endif + +#if defined(OPENSSL) +#include +#endif + +#if defined(_WIN32) || defined(_WIN64) + typedef WSABUF iobuf; +#else + typedef struct iovec iobuf; +#endif + +typedef struct +{ + int socket; + unsigned int index; + size_t headerlen; + char fixed_header[5]; /**< header plus up to 4 length bytes */ + size_t buflen, /**< total length of the buffer */ + datalen; /**< current length of data in buf */ + char* buf; +} socket_queue; + +typedef struct +{ + int socket, count; + size_t total; +#if defined(OPENSSL) + SSL* ssl; +#endif + size_t bytes; + iobuf iovecs[5]; + int frees[5]; +} pending_writes; + +#define SOCKETBUFFER_COMPLETE 0 +#if !defined(SOCKET_ERROR) + #define SOCKET_ERROR -1 +#endif +#define SOCKETBUFFER_INTERRUPTED -22 /* must be the same value as TCPSOCKET_INTERRUPTED */ + +int SocketBuffer_initialize(void); +void SocketBuffer_terminate(void); +void SocketBuffer_cleanup(int socket); +char* SocketBuffer_getQueuedData(int socket, size_t bytes, size_t* actual_len); +int SocketBuffer_getQueuedChar(int socket, char* c); +void SocketBuffer_interrupted(int socket, size_t actual_len); +char* SocketBuffer_complete(int socket); +void SocketBuffer_queueChar(int socket, char c); + +#if defined(OPENSSL) +int SocketBuffer_pendingWrite(int socket, SSL* ssl, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#else +int SocketBuffer_pendingWrite(int socket, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#endif +pending_writes* SocketBuffer_getWrite(int socket); +int SocketBuffer_writeComplete(int socket); +pending_writes* SocketBuffer_updateWrite(int socket, char* topic, char* payload); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/StackTrace.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/StackTrace.h new file mode 100644 index 0000000..c4f0d43 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/StackTrace.h @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#ifndef STACKTRACE_H_ +#define STACKTRACE_H_ + +#if defined(HIGH_PERFORMANCE) +#define NOSTACKTRACE 1 +#endif + +#include +#include "Log.h" +#include "Thread.h" + +#if defined(NOSTACKTRACE) +#define FUNC_ENTRY +#define FUNC_ENTRY_NOLOG +#define FUNC_ENTRY_MED +#define FUNC_ENTRY_MAX +#define FUNC_EXIT +#define FUNC_EXIT_NOLOG +#define FUNC_EXIT_MED +#define FUNC_EXIT_MAX +#define FUNC_EXIT_RC(x) +#define FUNC_EXIT_MED_RC(x) +#define FUNC_EXIT_MAX_RC(x) +#else +#if defined(_WIN32) || defined(_WIN64) +#define inline __inline +#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM) +#else +#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM) +#endif +#endif + +void StackTrace_entry(const char* name, int line, enum LOG_LEVELS trace); +void StackTrace_exit(const char* name, int line, void* return_value, enum LOG_LEVELS trace); + +void StackTrace_printStack(FILE* dest); +char* StackTrace_get(thread_id_type, char* buf, int bufsize); + +#endif /* STACKTRACE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Thread.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Thread.h new file mode 100644 index 0000000..29903f5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Thread.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + * Ian Craggs, Allan Stockdill-Mander - async client updates + * Ian Craggs - fix for bug #420851 + * Ian Craggs - change MacOS semaphore implementation + *******************************************************************************/ + +#if !defined(THREAD_H) +#define THREAD_H + +#include "MQTTExportDeclarations.h" + +#include "MQTTClient.h" + +#include "mutex_type.h" /* Needed for mutex_type */ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define thread_type HANDLE + #define thread_id_type DWORD + #define thread_return_type DWORD + #define thread_fn LPTHREAD_START_ROUTINE + #define cond_type HANDLE + #define sem_type HANDLE + #undef ETIMEDOUT + #define ETIMEDOUT WSAETIMEDOUT +#else + #include + + #define thread_type pthread_t + #define thread_id_type pthread_t + #define thread_return_type void* + typedef thread_return_type (*thread_fn)(void*); + typedef struct { pthread_cond_t cond; pthread_mutex_t mutex; } cond_type_struct; + typedef cond_type_struct *cond_type; + #if defined(OSX) + #include + typedef dispatch_semaphore_t sem_type; + #else + #include + typedef sem_t *sem_type; + #endif + + cond_type Thread_create_cond(int*); + int Thread_signal_cond(cond_type); + int Thread_wait_cond(cond_type condvar, int timeout); + int Thread_destroy_cond(cond_type); +#endif + +LIBMQTT_API thread_type Thread_start(thread_fn, void*); + +LIBMQTT_API mutex_type Thread_create_mutex(int*); +LIBMQTT_API int Thread_lock_mutex(mutex_type); +LIBMQTT_API int Thread_unlock_mutex(mutex_type); +int Thread_destroy_mutex(mutex_type); + +LIBMQTT_API thread_id_type Thread_getid(); + +sem_type Thread_create_sem(int*); +int Thread_wait_sem(sem_type sem, int timeout); +int Thread_check_sem(sem_type sem); +int Thread_post_sem(sem_type sem); +int Thread_destroy_sem(sem_type sem); + + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Tree.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Tree.h new file mode 100644 index 0000000..dfd70ab --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/Tree.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + + +#if !defined(TREE_H) +#define TREE_H + +#include /* for size_t definition */ + +/*BE +defm defTree(T) // macro to define a tree + +def T concat Node +{ + n32 ptr T concat Node "parent" + n32 ptr T concat Node "left" + n32 ptr T concat Node "right" + n32 ptr T id2str(T) + n32 suppress "size" +} + + +def T concat Tree +{ + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + n32 dec "count" + n32 dec suppress "size" +} + +endm + +defTree(INT) +defTree(STRING) +defTree(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct NodeStruct +{ + struct NodeStruct *parent, /**< pointer to parent tree node, in case we need it */ + *child[2]; /**< pointers to child tree nodes 0 = left, 1 = right */ + void* content; /**< pointer to element content */ + size_t size; /**< size of content */ + unsigned int red : 1; +} Node; + + +/** + * Structure to hold all data for one tree + */ +typedef struct +{ + struct + { + Node *root; /**< root node pointer */ + int (*compare)(void*, void*, int); /**< comparison function */ + } index[2]; + int indexes, /**< no of indexes into tree */ + count; /**< no of items */ + size_t size; /**< heap storage used */ + unsigned int heap_tracking : 1; /**< switch on heap tracking for this tree? */ + unsigned int allow_duplicates : 1; /**< switch to allow duplicate entries */ +} Tree; + + +Tree* TreeInitialize(int(*compare)(void*, void*, int)); +void TreeInitializeNoMalloc(Tree* aTree, int(*compare)(void*, void*, int)); +void TreeAddIndex(Tree* aTree, int(*compare)(void*, void*, int)); + +void* TreeAdd(Tree* aTree, void* content, size_t size); + +void* TreeRemove(Tree* aTree, void* content); + +void* TreeRemoveKey(Tree* aTree, void* key); +void* TreeRemoveKeyIndex(Tree* aTree, void* key, int index); + +void* TreeRemoveNodeIndex(Tree* aTree, Node* aNode, int index); + +void TreeFree(Tree* aTree); + +Node* TreeFind(Tree* aTree, void* key); +Node* TreeFindIndex(Tree* aTree, void* key, int index); + +Node* TreeNextElement(Tree* aTree, Node* curnode); + +int TreeIntCompare(void* a, void* b, int); +int TreePtrCompare(void* a, void* b, int); +int TreeStringCompare(void* a, void* b, int); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/VersionInfo.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/VersionInfo.h new file mode 100644 index 0000000..b3b3e78 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/VersionInfo.h @@ -0,0 +1,7 @@ +#ifndef VERSIONINFO_H +#define VERSIONINFO_H + +#define BUILD_TIMESTAMP "2021-02-11 12:10" +#define CLIENT_VERSION "1.3.8" + +#endif /* VERSIONINFO_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/WebSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/WebSocket.h new file mode 100644 index 0000000..e9f5765 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/WebSocket.h @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2018, 2020 Wind River Systems, Inc. and others. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(WEBSOCKET_H) +#define WEBSOCKET_H + +#include "MQTTPacket.h" + +/** + * WebSocket op codes + * @{ + */ +#define WebSocket_OP_CONTINUE 0x0 /* 0000 - continue frame */ +#define WebSocket_OP_TEXT 0x1 /* 0001 - text frame */ +#define WebSocket_OP_BINARY 0x2 /* 0010 - binary frame */ +#define WebSocket_OP_CLOSE 0x8 /* 1000 - close frame */ +#define WebSocket_OP_PING 0x9 /* 1001 - ping frame */ +#define WebSocket_OP_PONG 0xA /* 1010 - pong frame */ +/** @} */ + +/** + * Various close status codes + * @{ + */ +#define WebSocket_CLOSE_NORMAL 1000 +#define WebSocket_CLOSE_GOING_AWAY 1001 +#define WebSocket_CLOSE_PROTOCOL_ERROR 1002 +#define WebSocket_CLOSE_UNKNOWN_DATA 1003 +#define WebSocket_CLOSE_RESERVED 1004 +#define WebSocket_CLOSE_NO_STATUS_CODE 1005 /* reserved: not to be used */ +#define WebSocket_CLOSE_ABNORMAL 1006 /* reserved: not to be used */ +#define WebSocket_CLOSE_BAD_DATA 1007 +#define WebSocket_CLOSE_POLICY 1008 +#define WebSocket_CLOSE_MSG_TOO_BIG 1009 +#define WebSocket_CLOSE_NO_EXTENSION 1010 +#define WebScoket_CLOSE_UNEXPECTED 1011 +#define WebSocket_CLOSE_TLS_FAIL 1015 /* reserved: not be used */ +/** @} */ + +/* closes a websocket connection */ +void WebSocket_close(networkHandles *net, int status_code, const char *reason); + +/* sends upgrade request */ +int WebSocket_connect(networkHandles *net, const char *uri); + +/* obtain data from network socket */ +int WebSocket_getch(networkHandles *net, char* c); +char *WebSocket_getdata(networkHandles *net, size_t bytes, size_t* actual_len); +size_t WebSocket_framePos(); +void WebSocket_framePosSeekTo(size_t); + +/* send data out, in websocket format only if required */ +int WebSocket_putdatas(networkHandles* net, char** buf0, size_t* buf0len, PacketBuffers* bufs); + +/* releases any resources used by the websocket system */ +void WebSocket_terminate(void); + +/* handles websocket upgrade request */ +int WebSocket_upgrade(networkHandles *net); + +/* Notify the IP address and port of the endpoint to proxy, and wait connection to endpoint */ +int WebSocket_proxy_connect( networkHandles *net, int ssl, const char *hostname); + +#endif /* WEBSOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/mutex_type.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/mutex_type.h new file mode 100644 index 0000000..1e4b9e5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/mutex_type.h @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + *******************************************************************************/ +#if !defined(_MUTEX_TYPE_H_) +#define _MUTEX_TYPE_H_ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define mutex_type HANDLE +#else + #include + #define mutex_type pthread_mutex_t* +#endif + +#endif /* _MUTEX_TYPE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/utf-8.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/utf-8.h new file mode 100644 index 0000000..a7a4270 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/include/utf-8.h @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(UTF8_H) +#define UTF8_H + +int UTF8_validate(int len, const char *data); +int UTF8_validateString(const char* string); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libAR.a new file mode 100644 index 0000000..41d916b Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libOpenSSL_s.a new file mode 100644 index 0000000..a5de630 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libPahoMQTT_s.a new file mode 100644 index 0000000..4354100 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libar_posix_s.a new file mode 100644 index 0000000..1bd8f6b Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.53.0/SG4/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/Binary.lby b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/Binary.lby new file mode 100644 index 0000000..cd9b6f9 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/Binary.lby @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libAR.a new file mode 100644 index 0000000..235f5d6 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libOpenSSL_s.a new file mode 100644 index 0000000..cacaaf6 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libPahoMQTT_s.a new file mode 100644 index 0000000..4ee694f Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libar_posix_s.a new file mode 100644 index 0000000..2cb1bc8 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/Arm/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Base64.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Base64.h new file mode 100644 index 0000000..7022ce8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Base64.h @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2018 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(BASE64_H) +#define BASE64_H + +/** type for size of a buffer, it saves passing around @p size_t (unsigned long long or unsigned long int) */ +typedef unsigned int b64_size_t; +/** type for raw base64 data */ +typedef unsigned char b64_data_t; + +/** + * Decodes base64 data + * + * @param[out] out decoded data + * @param[in] out_len length of output buffer + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the amount of data decoded + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_decode( b64_data_t *out, b64_size_t out_len, + const char *in, b64_size_t in_len ); + +/** + * Size of buffer required to decode base64 data + * + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the decoded string would require + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_decodeLength( const char *in, b64_size_t in_len ); + +/** + * Encodes base64 data + * + * @param[out] out encode base64 string + * @param[in] out_len length of output buffer + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the amount of data encoded + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_encode( char *out, b64_size_t out_len, + const b64_data_t *in, b64_size_t in_len ); + +/** + * Size of buffer required to encode base64 data + * + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the encoded string would require + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_encodeLength( const b64_data_t *in, b64_size_t in_len ); + +#endif /* BASE64_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Clients.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Clients.h new file mode 100644 index 0000000..a3ddb1f --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Clients.h @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - add SSL support + * Ian Craggs - fix for bug 413429 - connectionLost not called + * Ian Craggs - change will payload to binary + * Ian Craggs - password to binary + * Ian Craggs - MQTT 5 support + *******************************************************************************/ + +#if !defined(CLIENTS_H) +#define CLIENTS_H + +#include +#include "MQTTTime.h" +#if defined(OPENSSL) +#if defined(_WIN32) || defined(_WIN64) +#include +#endif +#include +#endif +#include "MQTTClient.h" +#include "LinkedList.h" +#include "MQTTClientPersistence.h" + +/** + * Stored publication data to minimize copying + */ +typedef struct +{ + char *topic; + int topiclen; + char* payload; + int payloadlen; + int refcount; + uint8_t mask[4]; +} Publications; + +/** + * Client publication message data + */ +typedef struct +{ + int qos; + int retain; + int msgid; + int MQTTVersion; + MQTTProperties properties; + Publications *publish; + START_TIME_TYPE lastTouch; /**> used for retry and expiry */ + char nextMessageType; /**> PUBREC, PUBREL, PUBCOMP */ + int len; /**> length of the whole structure+data */ +} Messages; + +/** + * Client will message data + */ +typedef struct +{ + char *topic; + int payloadlen; + void *payload; + int retained; + int qos; +} willMessages; + +typedef struct +{ + int socket; + START_TIME_TYPE lastSent; + START_TIME_TYPE lastReceived; + START_TIME_TYPE lastPing; +#if defined(OPENSSL) + SSL* ssl; + SSL_CTX* ctx; + char *https_proxy; + char *https_proxy_auth; +#endif + char *http_proxy; + char *http_proxy_auth; + int websocket; /**< socket has been upgraded to use web sockets */ + char *websocket_key; + const MQTTClient_nameValue* httpHeaders; +} networkHandles; + + +/* connection states */ +/** no connection in progress, see connected value */ +#define NOT_IN_PROGRESS 0x0 +/** TCP connection in progress */ +#define TCP_IN_PROGRESS 0x1 +/** SSL connection in progress */ +#define SSL_IN_PROGRESS 0x2 +/** Websocket connection in progress */ +#define WEBSOCKET_IN_PROGRESS 0x3 +/** TCP completed, waiting for MQTT ACK */ +#define WAIT_FOR_CONNACK 0x4 +/** Proxy connection in progress */ +#define PROXY_CONNECT_IN_PROGRESS 0x5 +/** Disconnecting */ +#define DISCONNECTING -2 + +/** + * Data related to one client + */ +typedef struct +{ + char* clientID; /**< the string id of the client */ + const char* username; /**< MQTT v3.1 user name */ + int passwordlen; /**< MQTT password length */ + const void* password; /**< MQTT v3.1 binary password */ + unsigned int cleansession : 1; /**< MQTT V3 clean session flag */ + unsigned int cleanstart : 1; /**< MQTT V5 clean start flag */ + unsigned int connected : 1; /**< whether it is currently connected */ + unsigned int good : 1; /**< if we have an error on the socket we turn this off */ + unsigned int ping_outstanding : 1; + signed int connect_state : 4; + networkHandles net; /**< network info for this client */ + int msgID; /**< the MQTT message id */ + int keepAliveInterval; /**< the MQTT keep alive interval */ + int retryInterval; + int maxInflightMessages; /**< the max number of inflight outbound messages we allow */ + willMessages* will; /**< the MQTT will message, if any */ + List* inboundMsgs; /**< inbound in flight messages */ + List* outboundMsgs; /**< outbound in flight messages */ + List* messageQueue; /**< inbound complete but undelivered messages */ + unsigned int qentry_seqno; + void* phandle; /**< the persistence handle */ + MQTTClient_persistence* persistence; /**< a persistence implementation */ + MQTTPersistence_beforeWrite* beforeWrite; /**< persistence write callback */ + MQTTPersistence_afterRead* afterRead; /**< persistence read callback */ + void* beforeWrite_context; /**< context to be used with the persistence beforeWrite callbacks */ + void* afterRead_context; /**< context to be used with the persistence afterRead callback */ + void* context; /**< calling context - used when calling disconnect_internal */ + int MQTTVersion; /**< the version of MQTT being used, 3, 4 or 5 */ + int sessionExpiry; /**< MQTT 5 session expiry */ + char* httpProxy; /**< HTTP proxy for websockets */ + char* httpsProxy; /**< HTTPS proxy for websockets */ +#if defined(OPENSSL) + MQTTClient_SSLOptions *sslopts; /**< the SSL/TLS connect options */ + SSL_SESSION* session; /**< SSL session pointer for fast handhake */ +#endif +} Clients; + +int clientIDCompare(void* a, void* b); +int clientSocketCompare(void* a, void* b); + +/** + * Configuration data related to all clients + */ +typedef struct +{ + const char* version; + List* clients; +} ClientStates; + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Heap.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Heap.h new file mode 100644 index 0000000..f89a760 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Heap.h @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - use tree data structure instead of list + *******************************************************************************/ + + +#if !defined(HEAP_H) +#define HEAP_H + +#if defined(HIGH_PERFORMANCE) +#define NO_HEAP_TRACKING 1 +#endif + +#define PAHO_MEMORY_ERROR -99 + +#include "MQTTExportDeclarations.h" + +#include +#include + +#if !defined(NO_HEAP_TRACKING) + +#if !defined(TREE_C) +/** + * redefines malloc to use "mymalloc" so that heap allocation can be tracked + * @param x the size of the item to be allocated + * @return the pointer to the item allocated, or NULL + */ +#define malloc(x) mymalloc(__FILE__, __LINE__, x) + +/** + * redefines realloc to use "myrealloc" so that heap allocation can be tracked + * @param a the heap item to be reallocated + * @param b the new size of the item + * @return the new pointer to the heap item + */ +#define realloc(a, b) myrealloc(__FILE__, __LINE__, a, b) + +/** + * redefines free to use "myfree" so that heap allocation can be tracked + * @param x the size of the item to be freed + */ +#define free(x) myfree(__FILE__, __LINE__, x) + +#endif + +/** + * Information about the state of the heap. + */ +typedef struct +{ + size_t current_size; /**< current size of the heap in bytes */ + size_t max_size; /**< max size the heap has reached in bytes */ +} heap_info; + +#if defined(__cplusplus) + extern "C" { +#endif + +void* mymalloc(char*, int, size_t size); +void* myrealloc(char*, int, void* p, size_t size); +void myfree(char*, int, void* p); + +void Heap_scan(FILE* file); +int Heap_initialize(void); +void Heap_terminate(void); +LIBMQTT_API heap_info* Heap_get_info(void); +int HeapDump(FILE* file); +int HeapDumpString(FILE* file, char* str); +void* Heap_findItem(void* p); +void Heap_unlink(char* file, int line, void* p); +#ifdef __cplusplus + } +#endif + +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/LinkedList.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/LinkedList.h new file mode 100644 index 0000000..e390012 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/LinkedList.h @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + * Ian Craggs - change size types from int to size_t + *******************************************************************************/ + +#if !defined(LINKEDLIST_H) +#define LINKEDLIST_H + +#include /* for size_t definition */ + +/*BE +defm defList(T) + +def T concat Item +{ + at 4 + n32 ptr T concat Item suppress "next" + at 0 + n32 ptr T concat Item suppress "prev" + at 8 + n32 ptr T id2str(T) +} + +def T concat List +{ + n32 ptr T concat Item suppress "first" + n32 ptr T concat Item suppress "last" + n32 ptr T concat Item suppress "current" + n32 dec "count" + n32 suppress "size" +} +endm + +defList(INT) +defList(STRING) +defList(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct ListElementStruct +{ + struct ListElementStruct *prev, /**< pointer to previous list element */ + *next; /**< pointer to next list element */ + void* content; /**< pointer to element content */ +} ListElement; + + +/** + * Structure to hold all data for one list + */ +typedef struct +{ + ListElement *first, /**< first element in the list */ + *last, /**< last element in the list */ + *current; /**< current element in the list, for iteration */ + int count; /**< no of items */ + size_t size; /**< heap storage used */ +} List; + +void ListZero(List*); +List* ListInitialize(void); + +ListElement* ListAppend(List* aList, void* content, size_t size); +void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, size_t size); +ListElement* ListInsert(List* aList, void* content, size_t size, ListElement* index); + +int ListRemove(List* aList, void* content); +int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*)); +void* ListDetachHead(List* aList); +int ListRemoveHead(List* aList); +void* ListPopTail(List* aList); + +int ListDetach(List* aList, void* content); +int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*)); + +void ListFree(List* aList); +void ListEmpty(List* aList); +void ListFreeNoContent(List* aList); + +ListElement* ListNextElement(List* aList, ListElement** pos); +ListElement* ListPrevElement(List* aList, ListElement** pos); + +ListElement* ListFind(List* aList, void* content); +ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*)); + +int intcompare(void* a, void* b); +int stringcompare(void* a, void* b); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Log.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Log.h new file mode 100644 index 0000000..102e31d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Log.h @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + *******************************************************************************/ + +#if !defined(LOG_H) +#define LOG_H + +/*BE +map LOG_LEVELS +{ + "TRACE_MAXIMUM" 1 + "TRACE_MEDIUM" 2 + "TRACE_MINIMUM" 3 + "TRACE_PROTOCOL" 4 + + "ERROR" 5 + "SEVERE" 6 + "FATAL" 7 +} +BE*/ + +enum LOG_LEVELS { + INVALID_LEVEL = -1, + TRACE_MAXIMUM = 1, + TRACE_MEDIUM, + TRACE_MINIMUM, + TRACE_PROTOCOL, + LOG_ERROR, + LOG_SEVERE, + LOG_FATAL, +}; + + +/*BE +def trace_settings_type +{ + n32 map LOG_LEVELS "trace_level" + n32 dec "max_trace_entries" + n32 dec "trace_output_level" +} +BE*/ +typedef struct +{ + enum LOG_LEVELS trace_level; /**< trace level */ + int max_trace_entries; /**< max no of entries in the trace buffer */ + enum LOG_LEVELS trace_output_level; /**< trace level to output to destination */ +} trace_settings_type; + +extern trace_settings_type trace_settings; + +#define LOG_PROTOCOL TRACE_PROTOCOL +#define TRACE_MAX TRACE_MAXIMUM +#define TRACE_MIN TRACE_MINIMUM +#define TRACE_MED TRACE_MEDIUM + +typedef struct +{ + const char* name; + const char* value; +} Log_nameValue; + +int Log_initialize(Log_nameValue*); +void Log_terminate(void); + +void Log(enum LOG_LEVELS, int, const char *, ...); +void Log_stackTrace(enum LOG_LEVELS, int, int, int, const char*, int, int*); + +typedef void Log_traceCallback(enum LOG_LEVELS level, const char *message); +void Log_setTraceCallback(Log_traceCallback* callback); +void Log_setTraceLevel(enum LOG_LEVELS level); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTAsync.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTAsync.h new file mode 100644 index 0000000..f728ba5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTAsync.h @@ -0,0 +1,2345 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation + * Ian Craggs, Allan Stockdill-Mander - SSL connections + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - fix for bug 444103 - success/failure callbacks not invoked + * Ian Craggs - automatic reconnect and offline buffering (send while disconnected) + * Ian Craggs - binary will message + * Ian Craggs - binary password + * Ian Craggs - remove const on eyecatchers #168 + * Ian Craggs - MQTT 5.0 + *******************************************************************************/ + +/********************************************************************/ + +/** + * @cond MQTTAsync_main + * @mainpage Asynchronous MQTT client library for C + * + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An Asynchronous MQTT client library for C. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the Asynchronous MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions
  • + *
  • Connect the client to an MQTT server
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref publish
  • + *
  • @ref subscribe
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
  • @ref auto_reconnect
  • + *
  • @ref offline_publish
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTASYNC_H) +#define MQTTASYNC_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTASYNC_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTASYNC_FAILURE -1 + +/* error code -2 is MQTTAsync_PERSISTENCE_ERROR */ + +#define MQTTASYNC_PERSISTENCE_ERROR -2 + +/** + * Return code: The client is disconnected. + */ +#define MQTTASYNC_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTASYNC_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTASYNC_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTASYNC_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTASYNC_BAD_STRUCTURE -8 +/** + * Return code: A qos parameter is not 0, 1 or 2 + */ +#define MQTTASYNC_BAD_QOS -9 +/** + * Return code: All 65535 MQTT msgids are being used + */ +#define MQTTASYNC_NO_MORE_MSGIDS -10 +/** + * Return code: the request is being discarded when not complete + */ +#define MQTTASYNC_OPERATION_INCOMPLETE -11 +/** + * Return code: no more messages can be buffered + */ +#define MQTTASYNC_MAX_BUFFERED_MESSAGES -12 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTASYNC_SSL_NOT_SUPPORTED -13 + /** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if the TLS version of the library + * is linked with. + */ +#define MQTTASYNC_BAD_PROTOCOL -14 + /** + * Return code: don't use options for another version of MQTT + */ + #define MQTTASYNC_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the client's version of MQTT + */ + #define MQTTASYNC_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic + */ + #define MQTTASYNC_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 +/** + * MQTT version to connect with: 5 + */ +#define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTAsync_init_options; + +#define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt (0) + */ +LIBMQTT_API void MQTTAsync_global_init(MQTTAsync_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTAsync_create(). + */ +typedef void* MQTTAsync; +/** + * A value representing an MQTT message. A token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTAsync_publish(), + * MQTTAsync_publishMessage(), + * MQTTAsync_deliveryComplete(), and + * MQTTAsync_getPendingTokens()). + */ +typedef int MQTTAsync_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTAsync_publishMessage(), + * MQTTAsync_publish(), MQTTAsync_receive(), MQTTAsync_freeMessage() + * and MQTTAsync_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. This is an output parameter only. + */ + int dup; + /** The message identifier is reserved for internal use by the + * MQTT client and server. It is an output parameter only - writing + * to it will serve no purpose. It contains the MQTT message id of + * an incoming publish message. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTAsync_message; + +#define MQTTAsync_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTAsync_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTAsync_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTAsync_freeMessage must be called. + * To free the topic name storage, ::MQTTAsync_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTAsync_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTAsync_messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages to the server. The function is + * registered with the client library by passing it as an argument to MQTTAsync_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTAsync_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param token The ::MQTTAsync_token associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the tokens returned from calls to + * MQTTAsync_send() and MQTTAsync_sendMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTAsync_deliveryComplete(void* context, MQTTAsync_token token); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTAsync_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connectionLost(void* context, char* cause); + + +/** + * This is a callback function, which will be called when the client + * library successfully connects. This is superfluous when the connection + * is made in response to a MQTTAsync_connect call, because the onSuccess + * callback can be used. It is intended for use when automatic reconnect + * is enabled, so that when a reconnection attempt succeeds in the background, + * the application is notified and can take any required actions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connected(void* context, char* cause); + +/** + * This is a callback function, which will be called when the client + * library receives a disconnect packet. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param properties the properties in the disconnect packet. + * @param properties the reason code from the disconnect packet + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTAsync_disconnected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDisconnected(MQTTAsync handle, void* context, MQTTAsync_disconnected* co); + +/** The connect options that can be updated before an automatic reconnect. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQCD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name parameter. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + const char* username; + /** + * The password parameter of the MQTT authentication. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; +} MQTTAsync_connectData; + +#define MQTTAsync_connectData_initializer {{'M', 'Q', 'C', 'D'}, 0, NULL, {0, NULL}} + +/** + * This is a callback function which will allow the client application to update the + * connection data. + * @param data The connection data which can be modified by the application. + * @return Return a non-zero value to update the connect data, zero to keep the same data. + */ +typedef int MQTTAsync_updateConnectOptions(void* context, MQTTAsync_connectData* data); + +/** + * Sets the MQTTAsync_updateConnectOptions() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_updateConnectOptions() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setUpdateConnectOptions(MQTTAsync handle, void* context, MQTTAsync_updateConnectOptions* co); + +/** + * Sets the MQTTPersistence_beforeWrite() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setBeforePersistenceWrite(MQTTAsync handle, void* context, MQTTPersistence_beforeWrite* co); + + +/** + * Sets the MQTTPersistence_afterRead() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setAfterPersistenceRead(MQTTAsync handle, void* context, MQTTPersistence_afterRead* co); + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** A numeric code identifying the error. */ + int code; + /** Optional text explaining the error. Can be NULL. */ + const char *message; +} MQTTAsync_failureData; + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQFD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** The MQTT reason code returned. */ + enum MQTTReasonCodes reasonCode; + /** The MQTT properties on the ack, if any. */ + MQTTProperties properties; + /** A numeric code identifying the MQTT client library error. */ + int code; + /** Optional further text explaining the error. Can be NULL. */ + const char *message; + /** Packet type on which the failure occurred - used for publish QoS 1/2 exchanges*/ + int packet_type; +} MQTTAsync_failureData5; + +#define MQTTAsync_failureData5_initializer {{'M', 'Q', 'F', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, 0, NULL} + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribe, the granted QoS of the subscription returned by the server. + * Also for subscribeMany, if only 1 subscription was requested. */ + int qos; + /** For subscribeMany, if more than one subscription was requested, + * the list of granted QoSs of the subscriptions returned by the server. */ + int* qosList; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + } alt; +} MQTTAsync_successData; + + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + char struct_id[4]; /**< The eyecatcher for this structure. Will be MQSD. */ + int struct_version; /**< The version number of this structure. Will be 0 */ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + enum MQTTReasonCodes reasonCode; /**< MQTT V5 reason code returned */ + MQTTProperties properties; /**< MQTT V5 properties returned, if any */ + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } sub; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + /** For unsubscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } unsub; + } alt; +} MQTTAsync_successData5; + +#define MQTTAsync_successData5_initializer {{'M', 'Q', 'S', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer} + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onSuccess. + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess5(void* context, MQTTAsync_successData5* response); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure(void* context, MQTTAsync_failureData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onFailure. + * The application must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure5(void* context, MQTTAsync_failureData5* response); + +/** Structure to define call options. For MQTT 5.0 there is input data as well as that + * describing the response method. So there is now also a synonym ::MQTTAsync_callOptions + * to better reflect the use. This responseOptions name is kept for backward + * compatibility. + */ +typedef struct MQTTAsync_responseOptions +{ + /** The eyecatcher for this structure. Must be MQTR */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * if 0, no MQTTV5 options */ + int struct_version; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the API call fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * A token is returned from the call. It can be used to track + * the state of this request, both in the callbacks and in future calls + * such as ::MQTTAsync_waitForCompletion. + */ + MQTTAsync_token token; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /* + * MQTT V5 subscribe options, when used with subscribe only. + */ + MQTTSubscribe_options subscribeOptions; + /* + * MQTT V5 subscribe option count, when used with subscribeMany only. + * The number of entries in the subscribe_options_list array. + */ + int subscribeOptionsCount; + /* + * MQTT V5 subscribe option array, when used with subscribeMany only. + */ + MQTTSubscribe_options* subscribeOptionsList; +} MQTTAsync_responseOptions; + +#define MQTTAsync_responseOptions_initializer { {'M', 'Q', 'T', 'R'}, 1, NULL, NULL, 0, 0, NULL, NULL, MQTTProperties_initializer, MQTTSubscribe_options_initializer, 0, NULL} + +/** A synonym for responseOptions to better reflect its usage since MQTT 5.0 */ +typedef struct MQTTAsync_responseOptions MQTTAsync_callOptions; +#define MQTTAsync_callOptions_initializer MQTTAsync_responseOptions_initializer + +/** + * This function sets the global callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. If this callback is not set, an error will be returned. + * You must set this callback because otherwise there would be + * no way to deliver any incoming messages. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl, + MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc); + +/** + * This function sets the callback function for a connection lost event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed the callback functions to provide + * access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ + +LIBMQTT_API int MQTTAsync_setConnectionLostCallback(MQTTAsync handle, void* context, + MQTTAsync_connectionLost* cl); + +/** + * This function sets the callback function for a message arrived event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. You can set this to NULL if your application doesn't handle + * receipt of messages. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setMessageArrivedCallback(MQTTAsync handle, void* context, + MQTTAsync_messageArrived* ma); + +/** + * This function sets the callback function for a delivery complete event + * for a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDeliveryCompleteCallback(MQTTAsync handle, void* context, + MQTTAsync_deliveryComplete* dc); + +/** + * Sets the MQTTAsync_connected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co); + + +/** + * Reconnects a client with the previously used connect options. Connect + * must have previously been called for this to work. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_reconnect(MQTTAsync handle); + + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTAsync_persistence). See also MQTTAsync_destroy(). + * @param handle A pointer to an ::MQTTAsync handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of + * the library is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTASYNC_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTAsync_create(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTAsync_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2 or 3 + * 0 means no MQTTVersion + * 1 means no allowDisconnectedSendAtAnyTime, deleteOldestMessages, restoreMessages + * 2 means no persistQoS0 + */ + int struct_version; + /** Whether to allow messages to be sent when the client library is not connected. */ + int sendWhileDisconnected; + /** The maximum number of messages allowed to be buffered while not connected. */ + int maxBufferedMessages; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; + /** + * Allow sending of messages while disconnected before a first successful connect. + */ + int allowDisconnectedSendAtAnyTime; + /* + * When the maximum number of buffered messages is reached, delete the oldest rather than the newest. + */ + int deleteOldestMessages; + /* + * Restore messages from persistence on create - or clear it. + */ + int restoreMessages; + /* + * Persist QoS0 publish commands - an option to not persist them. + */ + int persistQoS0; +} MQTTAsync_createOptions; + +#define MQTTAsync_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_DEFAULT, 0, 0, 1, 1} + +#define MQTTAsync_createOptions_initializer5 { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_5, 0, 0, 1, 1} + + +LIBMQTT_API int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTAsync_createOptions* options); + +/** + * MQTTAsync_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTAsync_willOptions + * structure is passed in the MQTTAsync_connectOptions structure used in the + * MQTTAsync_connect() call that connects the client to the server. The pointer + * to MQTTAsync_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 indicates no binary will message support + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTAsync_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTAsync_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTAsync_willOptions; + +#define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTAsync_SSLOptions; + +#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** Utility structure where name/value pairs are needed */ +typedef struct +{ + const char* name; /**< name string */ + const char* value; /**< value string */ +} MQTTAsync_nameValue; + +/** + * MQTTAsync_connectOptions defines several settings that control the way the + * client connects to an MQTT server. Default values are set in + * MQTTAsync_connectOptions_initializer. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3 4 5 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no automatic reconnect options + * 4 signifies no binary password option (just string) + * 5 signifies no MQTTV5 properties + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + * Set to 0 if you do not want any keep alive processing. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTAsync_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This controls how many messages can be in-flight simultaneously. + */ + int maxInflight; + /** + * This is a pointer to an MQTTAsync_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTAsync_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTAsync_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTAsync_SSLOptions* ssl; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * The number of entries in the serverURIs array. + */ + int serverURIcount; + /** + * An array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a domain name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + */ + int MQTTVersion; + /** + * Reconnect automatically in the case of a connection being lost? + */ + int automaticReconnect; + /** + * Minimum retry interval in seconds. Doubled on each failed retry. + */ + int minRetryInterval; + /** + * Maximum retry interval in seconds. The doubling stops here on failed retries. + */ + int maxRetryInterval; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * MQTT V5 properties for connect + */ + MQTTProperties *connectProperties; + /** + * MQTT V5 properties for the will message in the connect + */ + MQTTProperties *willProperties; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * HTTP headers for websockets + */ + const MQTTAsync_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTAsync_connectOptions; + + +#define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + + +/** + * This function attempts to connect a previously-created client (see + * MQTTAsync_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTAsync_setCallbacks() prior to MQTTAsync_connect(). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options A pointer to a valid MQTTAsync_connectOptions + * structure. + * @return ::MQTTASYNC_SUCCESS if the client connect request was accepted. + * If the client was unable to connect to the server, an error code is + * returned via the onFailure callback, if set. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options); + +/** Options for the ::MQTTAsync_disconnect call */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTD. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. 0 signifies no V5 properties */ + int struct_version; + /** + * The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + */ + int timeout; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /** + * Reason code for MQTTV5 disconnect + */ + enum MQTTReasonCodes reasonCode; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; +} MQTTAsync_disconnectOptions; + +#define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 0, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +#define MQTTAsync_disconnectOptions_initializer5 { {'M', 'Q', 'T', 'D'}, 1, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTAsync_connectOptions.cleansession and MQTTAsync_connect()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions* options); + + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTAsync_isConnected(MQTTAsync handle); + + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTAsync_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTAsync_subscribe(MQTTAsync handle, const char* topic, int qos, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTAsync_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char* const* topic, const int* qos, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTAsync_unsubscribe(MQTTAsync handle, const char* topic, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const* topic, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to publish a message to a given topic (see also + * ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * This is optional and can be set to NULL. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_send(MQTTAsync handle, const char* destinationName, int payloadlen, const void* payload, int qos, + int retained, MQTTAsync_responseOptions* response); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTAsync_publish()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param msg A pointer to a valid MQTTAsync_message structure containing + * the payload and attributes of the message to be published. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_sendMessage(MQTTAsync handle, const char* destinationName, const MQTTAsync_message* msg, MQTTAsync_responseOptions* response); + + +/** + * This function sets a pointer to an array of tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param tokens The address of a pointer to an ::MQTTAsync_token. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTASYNC_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens); + +/** + * Tests whether a request corresponding to a token is complete. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @return 1 if the request has been completed, 0 if not. + */ +#define MQTTASYNC_TRUE 1 +LIBMQTT_API int MQTTAsync_isComplete(MQTTAsync handle, MQTTAsync_token token); + + +/** + * Waits for a request corresponding to a token to complete. This only works for + * messages with QoS greater than 0. A QoS 0 message has no MQTT token. + * This function will always return ::MQTTASYNC_SUCCESS for a QoS 0 message. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @param timeout the maximum time to wait for completion, in milliseconds + * @return ::MQTTASYNC_SUCCESS if the request has been completed in the time allocated, + * ::MQTTASYNC_FAILURE or ::MQTTASYNC_DISCONNECTED if not. + */ +LIBMQTT_API int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token token, unsigned long timeout); + + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTAsync_free() library function. + * @param msg The address of a pointer to the ::MQTTAsync_message structure + * to be freed. + */ +LIBMQTT_API void MQTTAsync_freeMessage(MQTTAsync_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTAsync_free(void* ptr); + +/** + * This function is used to allocate memory to be used or freed by the MQTT C client library, + * especially the data in the ::MQTTPersistence_afterRead and ::MQTTPersistence_beforeWrite + * callbacks. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. + * @param size The size of the memory to be allocated. + */ +LIBMQTT_API void* MQTTAsync_malloc(size_t size); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTAsync_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTAsync + * structure to be freed. + */ +LIBMQTT_API void MQTTAsync_destroy(MQTTAsync* handle); + + + +enum MQTTASYNC_TRACE_LEVELS +{ + MQTTASYNC_TRACE_MAXIMUM = 1, + MQTTASYNC_TRACE_MEDIUM, + MQTTASYNC_TRACE_MINIMUM, + MQTTASYNC_TRACE_PROTOCOL, + MQTTASYNC_TRACE_ERROR, + MQTTASYNC_TRACE_SEVERE, + MQTTASYNC_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTAsync_setTraceLevel(enum MQTTASYNC_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTAsync_traceCallback(enum MQTTASYNC_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTAsync_setTraceCallback(MQTTAsync_traceCallback* callback); + +/** + * This function returns version information about the library. + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void); + +/** + * Returns a pointer to a string representation of the error code, or NULL. + * Do not free after use. Returns NULL if the error code is unknown. + * @param code the MQTTASYNC_ return code. + * @return a static string representation of the error code. + */ +LIBMQTT_API const char* MQTTAsync_strerror(int code); + + +/*! + * @cond MQTTAsync_main + * @page async Threading + * The client application runs on several threads. + * Processing of handshaking and maintaining + * the network connection is performed in the background. + * This API is thread safe: functions may be called by multiple application + * threads. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(), + * MQTTAsync_connectionLost() and MQTTAsync_deliveryComplete()). + * In addition, some functions allow success and failure callbacks to be set + * for individual requests, in the ::MQTTAsync_responseOptions structure. Applications + * can be written as a chain of callback functions. + * + * @page callbacks Callbacks + * Any function from this API may be used within a callback. It is not advisable to + * use ::MQTTAsync_waitForCompletion within a callback, however, as it is the only + * API call that may take some time to complete, which may cause unpredictable + * behaviour. All the other API calls are intended to complete quickly, starting + * a request in the background, with success or failure notified by other callbacks. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * A log message will be written to highlight the issue, but it is up + * to the application to protect against this situation. + * + * @page auto_reconnect Automatic Reconnect + * The ability for the client library to reconnect automatically in the event + * of a connection failure was added in 1.1. The connection lost callback + * allows a flexible response to the loss of a connection, so almost any + * behaviour can be implemented in that way. Automatic reconnect does have the + * advantage of being a little simpler to use. + * + * To switch on automatic reconnect, the connect options field + * automaticReconnect should be set to non-zero. The minimum and maximum times + * before the next connection attempt can also be set, the defaults being 1 and + * 60 seconds. At each failure to reconnect, the retry interval is doubled until + * the maximum value is reached, and there it stays until the connection is + * successfully re-established whereupon it is reset. + * + * When a reconnection attempt is successful, the ::MQTTAsync_connected callback + * function is invoked, if set by calling ::MQTTAsync_setConnected. This allows + * the application to take any actions needed, such as amending subscriptions. + * + * @page offline_publish Publish While Disconnected + * This feature was not originally available because with persistence enabled, + * messages could be stored locally without ever knowing if they could be sent. + * The client application could have created the client with an erroneous broker + * address or port for instance. + * + * To enable messages to be published when the application is disconnected + * ::MQTTAsync_createWithOptions must be used instead of ::MQTTAsync_create to + * create the client object. The ::MQTTAsync_createOptions field sendWhileDisconnected + * must be set to non-zero, and the maxBufferedMessages field set as required - + * the default being 100. + * + * ::MQTTAsync_getPendingTokens can be called to return the ids of the messages + * waiting to be sent, or for which the sending process has not completed. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTAsync_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page publish Publication example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed\n"); + finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + finished = 1; +} + +void onSendFailure(void* context, MQTTAsync_failureData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message send failed token %d error code %d\n", response->token, response->code); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +void onSend(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message with token value %d delivery confirmed\n", response->token); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response ? response->code : 0); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + MQTTAsync_message pubmsg = MQTTAsync_message_initializer; + int rc; + + printf("Successful connection\n"); + opts.onSuccess = onSend; + opts.onFailure = onSendFailure; + opts.context = client; + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start sendMessage, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +int messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* m) +{ + // not expecting any messages + return 1; +} + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to create client object, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + if ((rc = MQTTAsync_setCallbacks(client, NULL, connlost, messageArrived, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callback, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (!finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + MQTTAsync_destroy(&client); + return rc; +} + + * @endcode + * @page subscribe Subscription example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int disc_finished = 0; +int subscribed = 0; +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + if (cause) + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTAsync_freeMessage(&message); + MQTTAsync_free(topicName); + return 1; +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed, rc %d\n", response->code); + disc_finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + disc_finished = 1; +} + +void onSubscribe(void* context, MQTTAsync_successData* response) +{ + printf("Subscribe succeeded\n"); + subscribed = 1; +} + +void onSubscribeFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Subscribe failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + int rc; + + printf("Successful connection\n"); + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + opts.onSuccess = onSubscribe; + opts.onFailure = onSubscribeFailure; + opts.context = client; + if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start subscribe, return code %d\n", rc); + finished = 1; + } +} + + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer; + int rc; + int ch; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) + != MQTTASYNC_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTAsync_setCallbacks(client, client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + while (!subscribed && !finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + if (finished) + goto exit; + + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + disc_opts.onSuccess = onDisconnect; + disc_opts.onFailure = onDisconnectFailure; + if ((rc = MQTTAsync_disconnect(client, &disc_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + while (!disc_finished) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + +destroy_exit: + MQTTAsync_destroy(&client); +exit: + return rc; +} + + * @endcode +* @page tracing Tracing + * + * Runtime tracing can be controlled by environment variables or API calls. + * + * #### Environment variables + * + * Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable. + * A value of ON, or stdout, prints to stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * #### Trace API calls + * + * MQTTAsync_traceCallback() is used to set a callback function which is called whenever trace + * information is available. This will be the same information as that printed if the + * environment variables were used to control the trace. + * + * The MQTTAsync_setTraceLevel() calls is used to set the maximum level of trace entries that will be + * passed to the callback function. The levels are: + * 1. ::MQTTASYNC_TRACE_MAXIMUM + * 2. ::MQTTASYNC_TRACE_MEDIUM + * 3. ::MQTTASYNC_TRACE_MINIMUM + * 4. ::MQTTASYNC_TRACE_PROTOCOL + * 5. ::MQTTASYNC_TRACE_ERROR + * 6. ::MQTTASYNC_TRACE_SEVERE + * 7. ::MQTTASYNC_TRACE_FATAL + * + * Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned. + * Choosing ::MQTTASYNC_TRACE_ERROR will cause ERROR, SEVERE and FATAL trace entries to be returned + * to the callback function. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ + +#if defined(__cplusplus) + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTAsyncUtils.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTAsyncUtils.h new file mode 100644 index 0000000..42a3145 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTAsyncUtils.h @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + +#if !defined(MQTTASYNCUTILS_H_) +#define MQTTASYNCUTILS_H_ + +#include "MQTTPacket.h" +#include "Thread.h" + +#define URI_TCP "tcp://" +#define URI_WS "ws://" +#define URI_WSS "wss://" + +enum MQTTAsync_threadStates +{ + STOPPED, STARTING, RUNNING, STOPPING +}; + +typedef struct +{ + MQTTAsync_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} qEntry; + +typedef struct +{ + int type; + MQTTAsync_onSuccess* onSuccess; + MQTTAsync_onFailure* onFailure; + MQTTAsync_onSuccess5* onSuccess5; + MQTTAsync_onFailure5* onFailure5; + MQTTAsync_token token; + void* context; + START_TIME_TYPE start_time; + MQTTProperties properties; + union + { + struct + { + int count; + char** topics; + int* qoss; + MQTTSubscribe_options opts; + MQTTSubscribe_options* optlist; + } sub; + struct + { + int count; + char** topics; + } unsub; + struct + { + char* destinationName; + int payloadlen; + void* payload; + int qos; + int retained; + } pub; + struct + { + int internal; + int timeout; + enum MQTTReasonCodes reasonCode; + } dis; + struct + { + int currentURI; + int MQTTVersion; /**< current MQTT version being used to connect */ + } conn; + } details; +} MQTTAsync_command; + +typedef struct MQTTAsync_struct +{ + char* serverURI; + int ssl; + int websocket; + Clients* c; + + /* "Global", to the client, callback definitions */ + MQTTAsync_connectionLost* cl; + MQTTAsync_messageArrived* ma; + MQTTAsync_deliveryComplete* dc; + void* clContext; /* the context to be associated with the conn lost callback*/ + void* maContext; /* the context to be associated with the msg arrived callback*/ + void* dcContext; /* the context to be associated with the deliv complete callback*/ + + MQTTAsync_connected* connected; + void* connected_context; /* the context to be associated with the connected callback*/ + + MQTTAsync_disconnected* disconnected; + void* disconnected_context; /* the context to be associated with the disconnected callback*/ + + MQTTAsync_updateConnectOptions* updateConnectOptions; + void* updateConnectOptions_context; + + /* Each time connect is called, we store the options that were used. These are reused in + any call to reconnect, or an automatic reconnect attempt */ + MQTTAsync_command connect; /* Connect operation properties */ + MQTTAsync_command disconnect; /* Disconnect operation properties */ + MQTTAsync_command* pending_write; /* Is there a socket write pending? */ + + List* responses; + unsigned int command_seqno; + + MQTTPacket* pack; + + /* added for offline buffering */ + MQTTAsync_createOptions* createOptions; + int shouldBeConnected; + int noBufferedMessages; /* the current number of buffered (publish) messages for this client */ + + /* added for automatic reconnect */ + int automaticReconnect; + int minRetryInterval; + int maxRetryInterval; + int serverURIcount; + char** serverURIs; + int connectTimeout; + + int currentInterval; + int currentIntervalBase; + START_TIME_TYPE lastConnectionFailedTime; + int retrying; + int reconnectNow; + + /* MQTT V5 properties */ + MQTTProperties* connectProps; + MQTTProperties* willProps; + +} MQTTAsyncs; + +typedef struct +{ + MQTTAsync_command command; + MQTTAsyncs* client; + unsigned int seqno; /* only used on restore */ + int not_restored; + char* key; /* if not_restored, this holds the key */ +} MQTTAsync_queuedCommand; + +void MQTTAsync_lock_mutex(mutex_type amutex); +void MQTTAsync_unlock_mutex(mutex_type amutex); +void MQTTAsync_terminate(void); +#if !defined(NO_PERSISTENCE) +int MQTTAsync_restoreCommands(MQTTAsyncs* client); +#endif +int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size); +void MQTTAsync_emptyMessageQueue(Clients* client); +void MQTTAsync_freeResponses(MQTTAsyncs* m); +void MQTTAsync_freeCommands(MQTTAsyncs* m); +int MQTTAsync_unpersistCommandsAndMessages(Clients* c); +void MQTTAsync_closeSession(Clients* client, enum MQTTReasonCodes reasonCode, MQTTProperties* props); +int MQTTAsync_disconnect1(MQTTAsync handle, const MQTTAsync_disconnectOptions* options, int internal); +int MQTTAsync_assignMsgId(MQTTAsyncs* m); +int MQTTAsync_getNoBufferedMessages(MQTTAsyncs* m); +void MQTTAsync_writeComplete(int socket, int rc); +void setRetryLoopInterval(int keepalive); + +#if defined(_WIN32) || defined(_WIN64) +#else +#define WINAPI +#endif + +thread_return_type WINAPI MQTTAsync_sendThread(void* n); +thread_return_type WINAPI MQTTAsync_receiveThread(void* n); + +#endif /* MQTTASYNCUTILS_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTClient.h new file mode 100644 index 0000000..da61357 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTClient.h @@ -0,0 +1,1945 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - remove const from eyecatchers #168 + *******************************************************************************/ + +/** + * @cond MQTTClient_internal + * @mainpage MQTT Client Library Internals + * In the beginning there was one MQTT C client library, MQTTClient, as implemented in MQTTClient.c + * This library was designed to be easy to use for applications which didn't mind if some of the calls + * blocked for a while. For instance, the MQTTClient_connect call will block until a successful + * connection has completed, or a connection has failed, which could be as long as the "connection + * timeout" interval, whose default is 30 seconds. + * + * However in mobile devices and other windowing environments, blocking on the GUI thread is a bad + * thing as it causes the user interface to freeze. Hence a new API, MQTTAsync, implemented + * in MQTTAsync.c, was devised. There are no blocking calls in this library, so it is well suited + * to GUI and mobile environments, at the expense of some extra complexity. + * + * Both libraries are designed to be sparing in the use of threads. So multiple client objects are + * handled by one or two threads, with a select call in Socket_getReadySocket(), used to determine + * when a socket has incoming data. This API is thread safe: functions may be called by multiple application + * threads, with the exception of ::MQTTClient_yield and ::MQTTClient_receive, which are intended + * for single threaded environments only. + * + * @endcond + * @cond MQTTClient_main + * @mainpage MQTT Client library for C + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An MQTT client library in C. + * + * These pages describe the original more synchronous API which might be + * considered easier to use. Some of the calls will block. For the new + * totally asynchronous API where no calls block, which is especially suitable + * for use in windowed environments, see the + * MQTT C Client Asynchronous API Documentation. + * The MQTTClient API is not thread safe, whereas the MQTTAsync API is. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions if multi-threaded (asynchronous mode) + * operation is being used (see @ref async).
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref pubsync
  • + *
  • @ref pubasync
  • + *
  • @ref subasync
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref callbacks
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENT_H) +#define MQTTCLIENT_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTCLIENT_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTCLIENT_FAILURE -1 + +/* error code -2 is MQTTCLIENT_PERSISTENCE_ERROR */ + +/** + * Return code: The client is disconnected. + */ +#define MQTTCLIENT_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTCLIENT_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTCLIENT_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTCLIENT_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTCLIENT_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTCLIENT_BAD_STRUCTURE -8 +/** + * Return code: A QoS value that falls outside of the acceptable range (0,1,2) + */ +#define MQTTCLIENT_BAD_QOS -9 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTCLIENT_SSL_NOT_SUPPORTED -10 + /** + * Return code: unrecognized MQTT version + */ + #define MQTTCLIENT_BAD_MQTT_VERSION -11 +/** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + */ +#define MQTTCLIENT_BAD_PROTOCOL -14 + /** + * Return code: option not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic on connect + */ + #define MQTTCLIENT_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 + /** + * MQTT version to connect with: 5 + */ + #define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTClient_init_options; + +#define MQTTClient_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library (0) + */ +LIBMQTT_API void MQTTClient_global_init(MQTTClient_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTClient_create(). + */ +typedef void* MQTTClient; +/** + * A value representing an MQTT message. A delivery token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTClient_publish(), + * MQTTClient_publishMessage(), + * MQTTClient_deliveryComplete(), + * MQTTClient_waitForCompletion() and + * MQTTClient_getPendingDeliveryTokens()). + */ +typedef int MQTTClient_deliveryToken; +typedef int MQTTClient_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTClient_publishMessage(), + * MQTTClient_publish(), MQTTClient_receive(), MQTTClient_freeMessage() + * and MQTTClient_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. + */ + int dup; + /** The message identifier is normally reserved for internal use by the + * MQTT client and server. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTClient_message; + +#define MQTTClient_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTClient_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTClient_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTClient_freeMessage must be called. + * To free the topic name storage, ::MQTTClient_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTClient_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTClient_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages. The function is registered with the + * client library by passing it as an argument to MQTTClient_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note:MQTTClient_deliveryComplete() is not called when messages are + * published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken dt); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTClient_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_connectionLost(void* context, char* cause); + +/** + * This function sets the callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Calling MQTTClient_setCallbacks() puts the + * client into multi-threaded mode. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. See @ref async for more information. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTClient_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTClient_messageArrived() callback + * function. This callback function must be set when you call + * MQTTClient_setCallbacks(), as otherwise there would be nowhere to deliver + * any incoming messages. + * @param dc A pointer to an MQTTClient_deliveryComplete() callback + * function. You can set this to NULL if your application publishes + * synchronously or if you do not want to check for successful delivery. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl, + MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc); + + +/** + * This is a callback function, which will be called when the a disconnect + * packet is received from the server. This applies to MQTT V5 and above only. + * @param context A pointer to the context value originally passed to + * ::MQTTClient_setDisconnected(), which contains any application-specific context. + * @param properties The MQTT V5 properties received with the disconnect, if any. + * @param reasonCode The MQTT V5 reason code received with the disconnect. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTClient_disconnected() callback function for a client. This will be called + * if a disconnect packet is received from the server. Only valid for MQTT V5 and above. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTClient_disconnected() callback + * function. NULL removes the callback setting. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setDisconnected(MQTTClient handle, void* context, MQTTClient_disconnected* co); + +/** + * This is a callback function, the MQTT V5 version of MQTTClient_deliveryComplete(). + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the completed delivery of messages. + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note: It is not called when messages are published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + * @param packet_type the last received packet type for this completion. For QoS 1 + * always PUBACK. For QoS 2 could be PUBREC or PUBCOMP. + * @param properties the MQTT V5 properties returned with the last packet from the server + * @param reasonCode the reason code returned from the server + */ +typedef void MQTTClient_published(void* context, int dt, int packet_type, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +LIBMQTT_API int MQTTClient_setPublished(MQTTClient handle, void* context, MQTTClient_published* co); + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTClient_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; +} MQTTClient_createOptions; + +#define MQTTClient_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, MQTTVERSION_DEFAULT } + +/** + * A version of :MQTTClient_create() with additional options. + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp or ssl. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @param options additional options for the create. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_createWithOptions(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTClient_createOptions* options); + +/** + * MQTTClient_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTClient_willOptions + * structure is passed in the MQTTClient_connectOptions structure used in the + * MQTTClient_connect() call that connects the client to the server. The pointer + * to MQTTClient_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 means there is no binary payload option + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload in string form. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTClient_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTClient_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTClient_willOptions; + +#define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTClient_SSLOptions; + +#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** + * MQTTClient_libraryInfo is used to store details relating to the currently used + * library such as the version in use, the time it was built and relevant openSSL + * options. + * There is one static instance of this struct in MQTTClient.c + */ + +typedef struct +{ + const char* name; + const char* value; +} MQTTClient_nameValue; + +/** + * This function returns version information about the library. + * no trace information will be returned. + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTClient_nameValue* MQTTClient_getVersionInfo(void); + +/** + * MQTTClient_connectOptions defines several settings that control the way the + * client connects to an MQTT server. + * + * Note: Default values are not defined for members of + * MQTTClient_connectOptions so it is good practice to specify all settings. + * If the MQTTClient_connectOptions structure is defined as an automatic + * variable, all members are set to random values and thus must be set by the + * client application. If the MQTTClient_connectOptions structure is defined + * as a static variable, initialization (in compliant compilers) sets all + * values to 0 (NULL for pointers). A #keepAliveInterval setting of 0 prevents + * correct operation of the client and so you must at least set a value + * for #keepAliveInterval. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3, 4, 5, 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no returned values + * 4 signifies no binary password option + * 5 signifies no maxInflightMessages and cleanstart + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTClient_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This is a boolean value that controls how many messages can be in-flight + * simultaneously. Setting reliable to true means that a published + * message must be completed (acknowledgements received) before another + * can be sent. Attempts to publish additional messages receive an + * ::MQTTCLIENT_MAX_MESSAGES_INFLIGHT return code. Setting this flag to + * false allows up to 10 messages to be in-flight. This can increase + * overall throughput in some circumstances. + */ + int reliable; + /** + * This is a pointer to an MQTTClient_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTClient_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTClient_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTClient_SSLOptions* ssl; + /** + * The number of entries in the optional serverURIs array. Defaults to 0. + */ + int serverURIcount; + /** + * An optional array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * If this list is empty (the default), the server URI specified on MQTTClient_create() + * is used. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + * MQTTVERSION_5 (5) = only try version 5.0 + */ + int MQTTVersion; + /** + * Returned from the connect when the MQTT version used to connect is 3.1.1 + */ + struct + { + const char* serverURI; /**< the serverURI connected to */ + int MQTTVersion; /**< the MQTT version used to connect with */ + int sessionPresent; /**< if the MQTT version is 3.1.1, the value of sessionPresent returned in the connack */ + } returned; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct + { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /** + * The maximum number of messages in flight + */ + int maxInflightMessages; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * HTTP headers for websockets + */ + const MQTTClient_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTClient_connectOptions; + +#define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +/** + * This function attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @return ::MQTTCLIENT_SUCCESS if the client successfully connects to the + * server. An error code is returned if the client was unable to connect to + * the server. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options); + +/** MQTT version 5.0 response information */ +typedef struct MQTTResponse +{ + int version; /* the version number of this structure */ + enum MQTTReasonCodes reasonCode; /* the MQTT 5.0 reason code returned */ + int reasonCodeCount; /* the number of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + enum MQTTReasonCodes* reasonCodes; /* a list of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + MQTTProperties* properties; /* optionally, the MQTT 5.0 properties returned */ +} MQTTResponse; + +#define MQTTResponse_initializer {1, MQTTREASONCODE_SUCCESS, 0, NULL, NULL} + +/** + * Frees the storage associated with the MQTT response. + * @param response the response structure to be freed + */ +LIBMQTT_API void MQTTResponse_free(MQTTResponse response); + +/** + * Attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using MQTT version 5.0 and the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @param connectProperties the MQTT 5.0 connect properties to use + * @param willProperties the MQTT 5.0 properties to set on the will message + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_connect5(MQTTClient handle, MQTTClient_connectOptions* options, + MQTTProperties* connectProperties, MQTTProperties* willProperties); + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTClient_connectOptions.cleansession and MQTTClient_connect()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param timeout The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTClient_disconnect(MQTTClient handle, int timeout); + +LIBMQTT_API int MQTTClient_disconnect5(MQTTClient handle, int timeout, enum MQTTReasonCodes reason, MQTTProperties* props); + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTClient_isConnected(MQTTClient handle); + + +/* Subscribe is synchronous. QoS list parameter is changed on return to granted QoSs. + Returns return code, MQTTCLIENT_SUCCESS == success, non-zero some sort of error (TBD) */ + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTClient_subscribe(MQTTClient handle, const char* topic, int qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribe5(MQTTClient handle, const char* topic, int qos, + MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribeMany5(MQTTClient handle, int count, char* const* topic, + int* qos, MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @return ::MQTTCLIENT_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTClient_unsubscribe(MQTTClient handle, const char* topic); + +/** + * This function attempts to remove an existing subscription made by the + * specified client using MQTT 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribe5(MQTTClient handle, const char* topic, MQTTProperties* props); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @return ::MQTTCLIENT_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client using MQTT version 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribeMany5(MQTTClient handle, int count, char* const* topic, MQTTProperties* props); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publishMessage()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publish(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, int qos, int retained, + MQTTClient_deliveryToken* dt); + +/** + * Attempts to publish a message to a given topic using MQTT version 5.0 (see also + * MQTTClient_publishMessage5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param properties the MQTT 5.0 properties to be used + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publish5(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, + int qos, int retained, MQTTProperties* properties, MQTTClient_deliveryToken* dt); +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publishMessage(MQTTClient handle, const char* topicName, MQTTClient_message* msg, MQTTClient_deliveryToken* dt); + + +/** + * Attempts to publish a message to the given topic using MQTT version 5.0 + * (see also + * MQTTClient_publish5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char* topicName, MQTTClient_message* msg, + MQTTClient_deliveryToken* dt); + +/** + * This function is called by the client application to synchronize execution + * of the main thread with completed publication of a message. When called, + * MQTTClient_waitForCompletion() blocks execution until the message has been + * successful delivered or the specified timeout has expired. See @ref async. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param dt The ::MQTTClient_deliveryToken that represents the message being + * tested for successful delivery. Delivery tokens are issued by the + * publishing functions MQTTClient_publish() and MQTTClient_publishMessage(). + * @param timeout The maximum time to wait in milliseconds. + * @return ::MQTTCLIENT_SUCCESS if the message was successfully delivered. + * An error code is returned if the timeout expires or there was a problem + * checking the token. + */ +LIBMQTT_API int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken dt, unsigned long timeout); + + +/** + * This function sets a pointer to an array of delivery tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param tokens The address of a pointer to an ::MQTTClient_deliveryToken. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTCLIENT_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTClient_getPendingDeliveryTokens(MQTTClient handle, MQTTClient_deliveryToken **tokens); + +/** + * When implementing a single-threaded client, call this function periodically + * to allow processing of message retries and to send MQTT keepalive pings. + * If the application is calling MQTTClient_receive() regularly, then it is + * not necessary to call this function. + */ +LIBMQTT_API void MQTTClient_yield(void); + +/** + * This function performs a synchronous receive of incoming messages. It should + * be used only when the client application has not set callback methods to + * support asynchronous receipt of messages (see @ref async and + * MQTTClient_setCallbacks()). Using this function allows a single-threaded + * client subscriber application to be written. When called, this function + * blocks until the next message arrives or the specified timeout expires + *(see also MQTTClient_yield()). + * + * Important note: The application must free() the memory allocated + * to the topic and the message when processing is complete (see + * MQTTClient_freeMessage()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The address of a pointer to a topic. This function + * allocates the memory for the topic and returns it to the application + * by setting topicName to point to the topic. + * @param topicLen The length of the topic. If the return code from this + * function is ::MQTTCLIENT_TOPICNAME_TRUNCATED, the topic contains embedded + * NULL characters and the full topic should be retrieved by using + * topicLen. + * @param message The address of a pointer to the received message. This + * function allocates the memory for the message and returns it to the + * application by setting message to point to the received message. + * The pointer is set to NULL if the timeout expires. + * @param timeout The length of time to wait for a message in milliseconds. + * @return ::MQTTCLIENT_SUCCESS or ::MQTTCLIENT_TOPICNAME_TRUNCATED if a + * message is received. ::MQTTCLIENT_SUCCESS can also indicate that the + * timeout expired, in which case message is NULL. An error code is + * returned if there was a problem trying to receive a message. + */ +LIBMQTT_API int MQTTClient_receive(MQTTClient handle, char** topicName, int* topicLen, MQTTClient_message** message, + unsigned long timeout); + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTClient_free() library function. + * @param msg The address of a pointer to the ::MQTTClient_message structure + * to be freed. + */ +LIBMQTT_API void MQTTClient_freeMessage(MQTTClient_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client libary and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTClient_free(void* ptr); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTClient_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTClient + * structure to be freed. + */ +LIBMQTT_API void MQTTClient_destroy(MQTTClient* handle); + + +enum MQTTCLIENT_TRACE_LEVELS +{ + MQTTCLIENT_TRACE_MAXIMUM = 1, + MQTTCLIENT_TRACE_MEDIUM, + MQTTCLIENT_TRACE_MINIMUM, + MQTTCLIENT_TRACE_PROTOCOL, + MQTTCLIENT_TRACE_ERROR, + MQTTCLIENT_TRACE_SEVERE, + MQTTCLIENT_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTClient_setTraceLevel(enum MQTTCLIENT_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTClient_traceCallback(enum MQTTCLIENT_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTClient_setTraceCallback(MQTTClient_traceCallback* callback); + +/** + * Sets the timeout value for un/subscribe commands when waiting for the un/suback response from + * the server. Values less than 5000 are not allowed. + * @param handle A valid client handle from a successful call to MQTTClient_create(). + * @param milliSeconds the maximum number of milliseconds to wait + * @return MQTTCLIENT_SUCCESS or MQTTCLIENT_FAILURE + */ +LIBMQTT_API int MQTTClient_setCommandTimeout(MQTTClient handle, unsigned long milliSeconds); + +/** + * Returns a pointer to the string representation of the error or NULL. + * + * Do not free after use. Returns NULL if the error code is unknown. + */ +LIBMQTT_API const char* MQTTClient_strerror(int code); + +#if defined(__cplusplus) + } +#endif + +#endif + +/*! + * @cond MQTTClient_main + * @page async Asynchronous vs synchronous client applications + * This client library supports two modes of operation. These are referred to + * as synchronous and asynchronous modes. If your application + * calls MQTTClient_setCallbacks(), this puts the client into asynchronous + * mode, otherwise it operates in synchronous mode. + * + * In synchronous mode, the client application runs on a single thread. + * Messages are published using the MQTTClient_publish() and + * MQTTClient_publishMessage() functions. To determine that a QoS1 or QoS2 + * (see @ref qos) message has been successfully delivered, the application + * must call the MQTTClient_waitForCompletion() function. An example showing + * synchronous publication is shown in @ref pubsync. Receiving messages in + * synchronous mode uses the MQTTClient_receive() function. Client applications + * must call either MQTTClient_receive() or MQTTClient_yield() relatively + * frequently in order to allow processing of acknowledgements and the MQTT + * "pings" that keep the network connection to the server alive. + * + * In asynchronous mode, the client application runs on several threads. The + * main program calls functions in the client library to publish and subscribe, + * just as for the synchronous mode. Processing of handshaking and maintaining + * the network connection is performed in the background, however. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTClient_setCallbacks() (see MQTTClient_messageArrived(), + * MQTTClient_connectionLost() and MQTTClient_deliveryComplete()). + * This API is not thread safe however - it is not possible to call it from multiple + * threads without synchronization. You can use the MQTTAsync API for that. + * + * @page callbacks Callbacks + * You must not call a function from this API from within a callback otherwise + * a deadlock might result. The only exception to this is the ability to call + * connect within the connection lost callback, to allow a reconnect. + * + * When using MQTT 5.0, you can also call connect from within the disconnected + * callback, which is invoked when the MQTT server sends a disconnect packet. + * This server behaviour is allowed in MQTT 5.0, but not in MQTT 3.1.1, so the + * disconnected callback will never be invoked if you use MQTT 3.1.1. + * + * In particular, you must make a publish call within the message arrived callback. + * These restrictions are all lifted in the + * MQTTAsync API. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, or receive not called, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * It is up to the application to protect against this situation. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTClient_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTClient_subscribe() and MQTTClient_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page pubsync Synchronous publication example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for up to %d seconds for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID); + rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); + printf("Message with delivery token %d delivered\n", token); + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + printf("Failed to disconnect, return code %d\n", rc); + MQTTClient_destroy(&client); + return rc; +} + + * @endcode + * + * @page pubasync Asynchronous publication example +@code{.c} +#include +#include +#include +#include "MQTTClient.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + deliveredtoken = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (deliveredtoken != token) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } + +destroy_exit: + MQTTClient_destroy(&client); + +exit: + return rc; +} + + * @endcode + * @page subasync Asynchronous subscription example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +volatile MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + if ((rc = MQTTClient_subscribe(client, TOPIC, QOS)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to subscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + int ch; + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + if ((rc = MQTTClient_unsubscribe(client, TOPIC)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to unsubscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } +destroy_exit: + MQTTClient_destroy(&client); +exit: + return rc; +} + + * @endcode + * @page tracing Tracing + * + * Runtime tracing is controlled by environment variables. + * + * Tracing is switched on by setting MQTT_C_CLIENT_TRACE. A value of ON, or stdout, prints to + * stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTClientPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTClientPersistence.h new file mode 100644 index 0000000..d3caae4 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTClientPersistence.h @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** + * @file + * \brief This structure represents a persistent data store, used to store + * outbound and inbound messages, in order to achieve reliable messaging. + * + * The MQTT Client persists QoS1 and QoS2 messages in order to meet the + * assurances of delivery associated with these @ref qos levels. The messages + * are saved in persistent storage + * The type and context of the persistence implementation are specified when + * the MQTT client is created (see MQTTClient_create()). The default + * persistence type (::MQTTCLIENT_PERSISTENCE_DEFAULT) uses a file system-based + * persistence mechanism. The persistence_context argument passed to + * MQTTClient_create() when using the default peristence is a string + * representing the location of the persistence directory. If the context + * argument is NULL, the working directory will be used. + * + * To use memory-based persistence, an application passes + * ::MQTTCLIENT_PERSISTENCE_NONE as the persistence_type to + * MQTTClient_create(). This can lead to message loss in certain situations, + * but can be appropriate in some cases (see @ref qos). + * + * Client applications can provide their own persistence mechanism by passing + * ::MQTTCLIENT_PERSISTENCE_USER as the persistence_type. To implement a + * custom persistence mechanism, the application must pass an initialized + * ::MQTTClient_persistence structure as the persistence_context + * argument to MQTTClient_create(). + * + * If the functions defined return an ::MQTTCLIENT_PERSISTENCE_ERROR then the + * state of the persisted data should remain as it was prior to the function + * being called. For example, if Persistence_put() returns + * ::MQTTCLIENT_PERSISTENCE_ERROR, then it is assumed tha tthe persistent store + * does not contain the data that was passed to the function. Similarly, if + * Persistence_remove() returns ::MQTTCLIENT_PERSISTENCE_ERROR then it is + * assumed that the data to be removed is still held in the persistent store. + * + * It is up to the persistence implementation to log any error information that + * may be required to diagnose a persistence mechanism failure. + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENTPERSISTENCE_H) +#define MQTTCLIENTPERSISTENCE_H +/* +/// @endcond +*/ + +/** + * This persistence_type value specifies the default file system-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_DEFAULT 0 +/** + * This persistence_type value specifies a memory-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_NONE 1 +/** + * This persistence_type value specifies an application-specific + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_USER 2 + +/** + * Application-specific persistence functions must return this error code if + * there is a problem executing the function. + */ +#define MQTTCLIENT_PERSISTENCE_ERROR -2 + +/** + * @brief Initialize the persistent store. + * + * Either open the existing persistent store for this client ID or create a new + * one if one doesn't exist. If the persistent store is already open, return + * without taking any action. + * + * An application can use the same client identifier to connect to many + * different servers. The clientid in conjunction with the + * serverURI uniquely identifies the persistence store required. + * + * @param handle The address of a pointer to a handle for this persistence + * implementation. This function must set handle to a valid reference to the + * persistence following a successful return. + * The handle pointer is passed as an argument to all the other + * persistence functions. It may include the context parameter and/or any other + * data for use by the persistence functions. + * @param clientID The client identifier for which the persistent store should + * be opened. + * @param serverURI The connection string specified when the MQTT client was + * created (see MQTTClient_create()). + * @param context A pointer to any data required to initialize the persistent + * store (see ::MQTTClient_persistence). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_open)(void** handle, const char* clientID, const char* serverURI, void* context); + +/** + * @brief Close the persistent store referred to by the handle. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_close)(void* handle); + +/** + * @brief Put the specified data into the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string used as the key for the data to be put in the store. The + * key is later used to retrieve data from the store with Persistence_get(). + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers associated with + * this key. + * @param buflens An array of lengths of the data buffers. buflen[n] + * gives the length of buffer[n]. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_put)(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); + +/** + * @brief Retrieve the specified data from the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be retrieved. This is + * the same key used to save the data to the store with Persistence_put(). + * @param buffer The address of a pointer to a buffer. This function sets the + * pointer to point at the retrieved data, if successful. + * @param buflen The address of an int that is set to the length of + * buffer by this function if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_get)(void* handle, char* key, char** buffer, int* buflen); + +/** + * @brief Remove the data for the specified key from the store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be removed from the + * store. This is the same key used to save the data to the store with + * Persistence_put(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_remove)(void* handle, char* key); + +/** + * @brief Returns the keys in this persistent data store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param keys The address of a pointer to pointers to strings. Assuming + * successful execution, this function allocates memory to hold the returned + * keys (strings used to store the data with Persistence_put()). It also + * allocates memory to hold an array of pointers to these strings. keys + * is set to point to the array of pointers to strings. + * @param nkeys A pointer to the number of keys in this persistent data store. + * This function sets the number of keys, if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_keys)(void* handle, char*** keys, int* nkeys); + +/** + * @brief Clears the persistence store, so that it no longer contains any + * persisted data. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_clear)(void* handle); + +/** + * @brief Returns whether any data has been persisted using the specified key. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key The string to be tested for existence in the store. + * @return Return 0 if the key was found in the store, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_containskey)(void* handle, char* key); + +/** + * @brief A structure containing the function pointers to a persistence + * implementation and the context or state that will be shared across all + * the persistence functions. + */ +typedef struct { + /** + * A pointer to any data required to initialize the persistent store. + */ + void* context; + /** + * A function pointer to an implementation of Persistence_open(). + */ + Persistence_open popen; + /** + * A function pointer to an implementation of Persistence_close(). + */ + Persistence_close pclose; + /** + * A function pointer to an implementation of Persistence_put(). + */ + Persistence_put pput; + /** + * A function pointer to an implementation of Persistence_get(). + */ + Persistence_get pget; + /** + * A function pointer to an implementation of Persistence_remove(). + */ + Persistence_remove premove; + /** + * A function pointer to an implementation of Persistence_keys(). + */ + Persistence_keys pkeys; + /** + * A function pointer to an implementation of Persistence_clear(). + */ + Persistence_clear pclear; + /** + * A function pointer to an implementation of Persistence_containskey(). + */ + Persistence_containskey pcontainskey; +} MQTTClient_persistence; + + +/** + * A callback which is invoked just before a write to persistence. This can be + * used to transform the data, for instance to encrypt it. + * @param context The context as set in ::MQTTAsync_setBeforePersistenceWrite + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers. + * @param buflens An array of lengths of the data buffers. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_beforeWrite(void* context, int bufcount, char* buffers[], int buflens[]); + + +/** + * A callback which is invoked just after a read from persistence. This can be + * used to transform the data, for instance to decrypt it. + * @param context The context as set in ::MQTTAsync_setAfterPersistenceRead + * @param buffer The address of a pointer to a buffer. + * @param buflen The address of an int that is the length of the buffer. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_afterRead(void* context, char** buffer, int* buflen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTExportDeclarations.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTExportDeclarations.h new file mode 100644 index 0000000..d492ef1 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTExportDeclarations.h @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 Andreas Walter + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Andreas Walter - initially moved export declarations into separate fle + *******************************************************************************/ + +#if !defined(EXPORTDECLARATIONS_H) +#define EXPORTDECLARATIONS_H + +#if defined(_WIN32) || defined(_WIN64) +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __declspec(dllexport) +# elif defined(PAHO_MQTT_IMPORTS) +# define LIBMQTT_API __declspec(dllimport) +# else +# define LIBMQTT_API +# endif +#else +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __attribute__ ((visibility ("default"))) +# else +# define LIBMQTT_API extern +# endif +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPacket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPacket.h new file mode 100644 index 0000000..658404a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPacket.h @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - big endian Linux reversed definition + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKET_H) +#define MQTTPACKET_H + +#include "Socket.h" +#if defined(OPENSSL) +#include "SSLSocket.h" +#endif +#include "LinkedList.h" +#include "Clients.h" + +typedef unsigned int bool; +typedef void* (*pf)(int, unsigned char, char*, size_t); + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" + +enum errors +{ + MQTTPACKET_BAD = -4, + MQTTPACKET_BUFFER_TOO_SHORT = -2, + MQTTPACKET_READ_ERROR = -1, + MQTTPACKET_READ_COMPLETE +}; + + +enum msgTypes +{ + CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, + PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, + PINGREQ, PINGRESP, DISCONNECT, AUTH +}; + +#if defined(__linux__) +#include +#if __BYTE_ORDER == __BIG_ENDIAN + #define REVERSED 1 +#endif +#endif + +/** + * Bitfields for the MQTT header byte. + */ +typedef union +{ + /*unsigned*/ char byte; /**< the whole byte */ +#if defined(REVERSED) + struct + { + unsigned int type : 4; /**< message type nibble */ + bool dup : 1; /**< DUP flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool retain : 1; /**< retained flag bit */ + } bits; +#else + struct + { + bool retain : 1; /**< retained flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool dup : 1; /**< DUP flag bit */ + unsigned int type : 4; /**< message type nibble */ + } bits; +#endif +} Header; + + +/** + * Data for a connect packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connect flags */ +#if defined(REVERSED) + struct + { + bool username : 1; /**< 3.1 user name */ + bool password : 1; /**< 3.1 password */ + bool willRetain : 1; /**< will retain setting */ + unsigned int willQoS : 2; /**< will QoS value */ + bool will : 1; /**< will flag */ + bool cleanstart : 1; /**< cleansession flag */ + int : 1; /**< unused */ + } bits; +#else + struct + { + int : 1; /**< unused */ + bool cleanstart : 1; /**< cleansession flag */ + bool will : 1; /**< will flag */ + unsigned int willQoS : 2; /**< will QoS value */ + bool willRetain : 1; /**< will retain setting */ + bool password : 1; /**< 3.1 password */ + bool username : 1; /**< 3.1 user name */ + } bits; +#endif + } flags; /**< connect flags byte */ + + char *Protocol, /**< MQTT protocol name */ + *clientID, /**< string client id */ + *willTopic, /**< will topic */ + *willMsg; /**< will payload */ + + int keepAliveTimer; /**< keepalive timeout value in seconds */ + unsigned char version; /**< MQTT version number */ +} Connect; + + +/** + * Data for a connack packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connack flags */ +#if defined(REVERSED) + struct + { + unsigned int reserved : 7; /**< message type nibble */ + bool sessionPresent : 1; /**< was a session found on the server? */ + } bits; +#else + struct + { + bool sessionPresent : 1; /**< was a session found on the server? */ + unsigned int reserved : 7; /**< message type nibble */ + } bits; +#endif + } flags; /**< connack flags byte */ + unsigned char rc; /**< connack reason code */ + unsigned int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Connack; + + +/** + * Data for a packet with header only. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ +} MQTTPacket; + + +/** + * Data for a suback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* qoss; /**< list of granted QoSs (MQTT 3/4) / reason codes (MQTT 5) */ +} Suback; + + +/** + * Data for an MQTT V5 unsuback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* reasonCodes; /**< list of reason codes */ +} Unsuback; + + +/** + * Data for a publish packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + char* topic; /**< topic string */ + int topiclen; + int msgId; /**< MQTT message id */ + char* payload; /**< binary payload, length delimited */ + int payloadlen; /**< payload length */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + uint8_t mask[4]; /**< the websockets mask the payload is masked with, if any */ +} Publish; + + +/** + * Data for one of the ack packets. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + unsigned char rc; /**< MQTT 5 reason code */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Ack; + +typedef Ack Puback; +typedef Ack Pubrec; +typedef Ack Pubrel; +typedef Ack Pubcomp; + +int MQTTPacket_encode(char* buf, size_t length); +int MQTTPacket_decode(networkHandles* net, size_t* value); +int readInt(char** pptr); +char* readUTF(char** pptr, char* enddata); +unsigned char readChar(char** pptr); +void writeChar(char** pptr, char c); +void writeInt(char** pptr, int anInt); +void writeUTF(char** pptr, const char* string); +void writeData(char** pptr, const void* data, int datalen); + +const char* MQTTPacket_name(int ptype); + +void* MQTTPacket_Factory(int MQTTVersion, networkHandles* net, int* error); +int MQTTPacket_send(networkHandles* net, Header header, char* buffer, size_t buflen, int free, int MQTTVersion); +int MQTTPacket_sends(networkHandles* net, Header header, PacketBuffers* buffers, int MQTTVersion); + +void* MQTTPacket_header_only(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +int MQTTPacket_send_disconnect(Clients* client, enum MQTTReasonCodes reason, MQTTProperties* props); + +void* MQTTPacket_publish(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freePublish(Publish* pack); +int MQTTPacket_send_publish(Publish* pack, int dup, int qos, int retained, networkHandles* net, const char* clientID); +int MQTTPacket_send_puback(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +void MQTTPacket_freeAck(Ack* pack); +void MQTTPacket_freeSuback(Suback* pack); +void MQTTPacket_freeUnsuback(Unsuback* pack); +int MQTTPacket_send_pubrec(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubrel(int MQTTVersion, int msgid, int dup, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubcomp(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); + +void MQTTPacket_free_packet(MQTTPacket* pack); + +void writeInt4(char** pptr, int anInt); +int readInt4(char** pptr); +void writeMQTTLenString(char** pptr, MQTTLenString lenstring); +int MQTTLenStringRead(MQTTLenString* lenstring, char** pptr, char* enddata); +int MQTTPacket_VBIlen(int rem_len); +int MQTTPacket_decodeBuf(char* buf, unsigned int* value); + +#include "MQTTPacketOut.h" + +#endif /* MQTTPACKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPacketOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPacketOut.h new file mode 100644 index 0000000..d962554 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPacketOut.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKETOUT_H) +#define MQTTPACKETOUT_H + +#include "MQTTPacket.h" + +int MQTTPacket_send_connect(Clients* client, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +void* MQTTPacket_connack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freeConnack(Connack* pack); + +int MQTTPacket_send_pingreq(networkHandles* net, const char* clientID); + +int MQTTPacket_send_subscribe(List* topics, List* qoss, MQTTSubscribe_options* opts, MQTTProperties* props, + int msgid, int dup, Clients* client); +void* MQTTPacket_suback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +int MQTTPacket_send_unsubscribe(List* topics, MQTTProperties* props, int msgid, int dup, Clients* client); +void* MQTTPacket_unsuback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPersistence.h new file mode 100644 index 0000000..ed2e0ce --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPersistence.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - async client updates + * Ian Craggs - fix for bug 432903 - queue persistence + * Ian Craggs - MQTT V5 updates + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCE_H) +#define MQTTPERSISTENCE_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include "Clients.h" +#include "MQTTProperties.h" + +/** Stem of the key for a sent PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_PUBLISH_SENT "s-" +/** Stem of the key for a sent PUBREL */ +#define PERSISTENCE_PUBREL "sc-" +/** Stem of the key for a received PUBLISH QoS2 */ +#define PERSISTENCE_PUBLISH_RECEIVED "r-" + +/** Stem of the key for a sent MQTT V5 PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_V5_PUBLISH_SENT "s5-" +/** Stem of the key for a sent MQTT V5 PUBREL */ +#define PERSISTENCE_V5_PUBREL "sc5-" +/** Stem of the key for a received MQTT V5 PUBLISH QoS2 */ +#define PERSISTENCE_V5_PUBLISH_RECEIVED "r5-" + +/** Stem of the key for an async client command */ +#define PERSISTENCE_COMMAND_KEY "c-" +/** Stem of the key for an MQTT V5 async client command */ +#define PERSISTENCE_V5_COMMAND_KEY "c5-" +/** Stem of the key for an client incoming message queue */ +#define PERSISTENCE_QUEUE_KEY "q-" +/** Stem of the key for an MQTT V5 incoming message queue */ +#define PERSISTENCE_V5_QUEUE_KEY "q5-" +/** Maximum length of a stem for a persistence key */ +#define PERSISTENCE_MAX_STEM_LENGTH 3 +/** Maximum allowed length of a persistence key */ +#define PERSISTENCE_MAX_KEY_LENGTH 9 +/** Maximum size of an integer sequence number appended to a persistence key */ +#define PERSISTENCE_SEQNO_LIMIT 1000000 /*10^(PERSISTENCE_MAX_KEY_LENGTH - PERSISTENCE_MAX_STEM_LENGTH)*/ + +int MQTTPersistence_create(MQTTClient_persistence** per, int type, void* pcontext); +int MQTTPersistence_initialize(Clients* c, const char* serverURI); +int MQTTPersistence_close(Clients* c); +int MQTTPersistence_clear(Clients* c); +int MQTTPersistence_restorePackets(Clients* c); +void* MQTTPersistence_restorePacket(int MQTTVersion, char* buffer, size_t buflen); +void MQTTPersistence_insertInOrder(List* list, void* content, size_t size); +int MQTTPersistence_putPacket(int socket, char* buf0, size_t buf0len, int count, + char** buffers, size_t* buflens, int htype, int msgId, int scr, int MQTTVersion); +int MQTTPersistence_remove(Clients* c, char* type, int qos, int msgId); +void MQTTPersistence_wrapMsgID(Clients *c); + +typedef struct +{ + char struct_id[4]; + int struct_version; + int payloadlen; + void* payload; + int qos; + int retained; + int dup; + int msgid; + MQTTProperties properties; +} MQTTPersistence_message; + +typedef struct +{ + MQTTPersistence_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} MQTTPersistence_qEntry; + +int MQTTPersistence_unpersistQueueEntry(Clients* client, MQTTPersistence_qEntry* qe); +int MQTTPersistence_persistQueueEntry(Clients* aclient, MQTTPersistence_qEntry* qe); +int MQTTPersistence_restoreMessageQueue(Clients* c); +#ifdef __cplusplus + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPersistenceDefault.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPersistenceDefault.h new file mode 100644 index 0000000..506b4da --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTPersistenceDefault.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCEDEFAULT_H) +#define MQTTPERSISTENCEDEFAULT_H + +/** 8.3 filesystem */ +#define MESSAGE_FILENAME_LENGTH 8 +/** Extension of the filename */ +#define MESSAGE_FILENAME_EXTENSION ".msg" + +/* prototypes of the functions for the default file system persistence */ +int pstopen(void** handle, const char* clientID, const char* serverURI, void* context); +int pstclose(void* handle); +int pstput(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); +int pstget(void* handle, char* key, char** buffer, int* buflen); +int pstremove(void* handle, char* key); +int pstkeys(void* handle, char*** keys, int* nkeys); +int pstclear(void* handle); +int pstcontainskey(void* handle, char* key); + +int pstmkdir(char *pPathname); + +#endif + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProperties.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProperties.h new file mode 100644 index 0000000..81b8e3a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProperties.h @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPROPERTIES_H) +#define MQTTPROPERTIES_H + +#include "MQTTExportDeclarations.h" + +#define MQTT_INVALID_PROPERTY_ID -2 + +/** The one byte MQTT V5 property indicator */ +enum MQTTPropertyCodes { + MQTTPROPERTY_CODE_PAYLOAD_FORMAT_INDICATOR = 1, /**< The value is 1 */ + MQTTPROPERTY_CODE_MESSAGE_EXPIRY_INTERVAL = 2, /**< The value is 2 */ + MQTTPROPERTY_CODE_CONTENT_TYPE = 3, /**< The value is 3 */ + MQTTPROPERTY_CODE_RESPONSE_TOPIC = 8, /**< The value is 8 */ + MQTTPROPERTY_CODE_CORRELATION_DATA = 9, /**< The value is 9 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIER = 11, /**< The value is 11 */ + MQTTPROPERTY_CODE_SESSION_EXPIRY_INTERVAL = 17, /**< The value is 17 */ + MQTTPROPERTY_CODE_ASSIGNED_CLIENT_IDENTIFER = 18,/**< The value is 18 */ + MQTTPROPERTY_CODE_SERVER_KEEP_ALIVE = 19, /**< The value is 19 */ + MQTTPROPERTY_CODE_AUTHENTICATION_METHOD = 21, /**< The value is 21 */ + MQTTPROPERTY_CODE_AUTHENTICATION_DATA = 22, /**< The value is 22 */ + MQTTPROPERTY_CODE_REQUEST_PROBLEM_INFORMATION = 23,/**< The value is 23 */ + MQTTPROPERTY_CODE_WILL_DELAY_INTERVAL = 24, /**< The value is 24 */ + MQTTPROPERTY_CODE_REQUEST_RESPONSE_INFORMATION = 25,/**< The value is 25 */ + MQTTPROPERTY_CODE_RESPONSE_INFORMATION = 26, /**< The value is 26 */ + MQTTPROPERTY_CODE_SERVER_REFERENCE = 28, /**< The value is 28 */ + MQTTPROPERTY_CODE_REASON_STRING = 31, /**< The value is 31 */ + MQTTPROPERTY_CODE_RECEIVE_MAXIMUM = 33, /**< The value is 33*/ + MQTTPROPERTY_CODE_TOPIC_ALIAS_MAXIMUM = 34, /**< The value is 34 */ + MQTTPROPERTY_CODE_TOPIC_ALIAS = 35, /**< The value is 35 */ + MQTTPROPERTY_CODE_MAXIMUM_QOS = 36, /**< The value is 36 */ + MQTTPROPERTY_CODE_RETAIN_AVAILABLE = 37, /**< The value is 37 */ + MQTTPROPERTY_CODE_USER_PROPERTY = 38, /**< The value is 38 */ + MQTTPROPERTY_CODE_MAXIMUM_PACKET_SIZE = 39, /**< The value is 39 */ + MQTTPROPERTY_CODE_WILDCARD_SUBSCRIPTION_AVAILABLE = 40,/**< The value is 40 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIERS_AVAILABLE = 41,/**< The value is 41 */ + MQTTPROPERTY_CODE_SHARED_SUBSCRIPTION_AVAILABLE = 42/**< The value is 241 */ +}; + +/** + * Returns a printable string description of an MQTT V5 property code. + * @param value an MQTT V5 property code. + * @return the printable string description of the input property code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTPropertyName(enum MQTTPropertyCodes value); + +/** The one byte MQTT V5 property type */ +enum MQTTPropertyTypes { + MQTTPROPERTY_TYPE_BYTE, + MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER, + MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER, + MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER, + MQTTPROPERTY_TYPE_BINARY_DATA, + MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING, + MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR +}; + +/** + * Returns the MQTT V5 type code of an MQTT V5 property. + * @param value an MQTT V5 property code. + * @return the MQTT V5 type code of the input property. -1 if the code was not found. + */ +LIBMQTT_API int MQTTProperty_getType(enum MQTTPropertyCodes value); + +/** + * The data for a length delimited string + */ +typedef struct +{ + int len; /**< the length of the string */ + char* data; /**< pointer to the string data */ +} MQTTLenString; + + +/** + * Structure to hold an MQTT version 5 property of any type + */ +typedef struct +{ + enum MQTTPropertyCodes identifier; /**< The MQTT V5 property id. A multi-byte integer. */ + /** The value of the property, as a union of the different possible types. */ + union { + unsigned char byte; /**< holds the value of a byte property type */ + unsigned short integer2; /**< holds the value of a 2 byte integer property type */ + unsigned int integer4; /**< holds the value of a 4 byte integer property type */ + struct { + MQTTLenString data; /**< The value of a string property, or the name of a user property. */ + MQTTLenString value; /**< The value of a user property. */ + }; + } value; +} MQTTProperty; + +/** + * MQTT version 5 property list + */ +typedef struct MQTTProperties +{ + int count; /**< number of property entries in the array */ + int max_count; /**< max number of properties that the currently allocated array can store */ + int length; /**< mbi: byte length of all properties */ + MQTTProperty *array; /**< array of properties */ +} MQTTProperties; + +#define MQTTProperties_initializer {0, 0, 0, NULL} + +/** + * Returns the length of the properties structure when serialized ready for network transmission. + * @param props an MQTT V5 property structure. + * @return the length in bytes of the properties when serialized. + */ +int MQTTProperties_len(MQTTProperties* props); + +/** + * Add a property pointer to the property array. There is no memory allocation. + * @param props The property list to add the property to. + * @param prop The property to add to the list. + * @return 0 on success, -1 on failure. + */ +LIBMQTT_API int MQTTProperties_add(MQTTProperties* props, const MQTTProperty* prop); + +/** + * Serialize the given property list to a character buffer, e.g. for writing to the network. + * @param pptr pointer to the buffer - move the pointer as we add data + * @param properties pointer to the property list, can be NULL + * @return whether the write succeeded or not: number of bytes written, or < 0 on failure. + */ +int MQTTProperties_write(char** pptr, const MQTTProperties* properties); + +/** + * Reads a property list from a character buffer into an array. + * @param properties pointer to the property list to be filled. Should be initalized but empty. + * @param pptr pointer to the character buffer. + * @param enddata pointer to the end of the character buffer so we don't read beyond. + * @return 1 if the properties were read successfully. + */ +int MQTTProperties_read(MQTTProperties* properties, char** pptr, char* enddata); + +/** + * Free all memory allocated to the property list, including any to individual properties. + * @param properties pointer to the property list. + */ +LIBMQTT_API void MQTTProperties_free(MQTTProperties* properties); + +/** + * Copy the contents of a property list, allocating additional memory if needed. + * @param props pointer to the property list. + * @return the duplicated property list. + */ +LIBMQTT_API MQTTProperties MQTTProperties_copy(const MQTTProperties* props); + +/** + * Checks if property list contains a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return 1 if found, 0 if not. + */ +LIBMQTT_API int MQTTProperties_hasProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the number of instances of a property id. Most properties can exist only once. + * User properties and subscription ids can exist more than once. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the number of times found. Can be 0. + */ +LIBMQTT_API int MQTTProperties_propertyCount(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property. The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValue(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property when it's not the only instance. + * The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValueAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +/** + * Returns a pointer to the property structure for a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns a pointer to the property structure for a specific property when it's not the only instance. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getPropertyAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +#endif /* MQTTPROPERTIES_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProtocol.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProtocol.h new file mode 100644 index 0000000..52bcd15 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProtocol.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - MQTT 3.1.1 updates + *******************************************************************************/ + +#if !defined(MQTTPROTOCOL_H) +#define MQTTPROTOCOL_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +typedef struct +{ + int socket; + Publications* p; +} pending_write; + + +typedef struct +{ + List publications; + unsigned int msgs_received; + unsigned int msgs_sent; + List pending_writes; /* for qos 0 writes not complete */ +} MQTTProtocol; + + +#include "MQTTProtocolOut.h" + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProtocolClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProtocolClient.h new file mode 100644 index 0000000..2d077af --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProtocolClient.h @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 updates + * Rong Xiang, Ian Craggs - C++ compatibility + * Ian Craggs - add debug definition of MQTTStrdup for when needed + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLCLIENT_H) +#define MQTTPROTOCOLCLIENT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Log.h" +#include "MQTTProtocol.h" +#include "Messages.h" +#include "MQTTProperties.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +int MQTTProtocol_startPublish(Clients* pubclient, Publish* publish, int qos, int retained, Messages** m); +Messages* MQTTProtocol_createMessage(Publish* publish, Messages** mm, int qos, int retained, int allocatePayload); +Publications* MQTTProtocol_storePublication(Publish* publish, int* len); +int messageIDCompare(void* a, void* b); +int MQTTProtocol_assignMsgId(Clients* client); +void MQTTProtocol_removePublication(Publications* p); +void Protocol_processPublication(Publish* publish, Clients* client, int allocatePayload); + +int MQTTProtocol_handlePublishes(void* pack, int sock); +int MQTTProtocol_handlePubacks(void* pack, int sock); +int MQTTProtocol_handlePubrecs(void* pack, int sock); +int MQTTProtocol_handlePubrels(void* pack, int sock); +int MQTTProtocol_handlePubcomps(void* pack, int sock); + +void MQTTProtocol_closeSession(Clients* c, int sendwill); +void MQTTProtocol_keepalive(START_TIME_TYPE); +void MQTTProtocol_retry(START_TIME_TYPE, int, int); +void MQTTProtocol_freeClient(Clients* client); +void MQTTProtocol_emptyMessageList(List* msgList); +void MQTTProtocol_freeMessageList(List* msgList); + +char* MQTTStrncpy(char *dest, const char* src, size_t num); +char* MQTTStrdup(const char* src); + +//#define MQTTStrdup(src) MQTTStrncpy(malloc(strlen(src)+1), src, strlen(src)+1) + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProtocolOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProtocolOut.h new file mode 100644 index 0000000..6a50155 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTProtocolOut.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - SNI support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLOUT_H) +#define MQTTPROTOCOLOUT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" +#include "Log.h" +#include "Messages.h" +#include "MQTTProtocol.h" +#include "MQTTProtocolClient.h" + +#define MQTT_DEFAULT_PORT 1883 +#define SECURE_MQTT_DEFAULT_PORT 8883 +#define WS_DEFAULT_PORT 80 + +size_t MQTTProtocol_addressPort(const char* uri, int* port, const char **topic, int default_port); +void MQTTProtocol_reconnect(const char* ip_address, Clients* client); +#if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#else +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#endif +int MQTTProtocol_handlePingresps(void* pack, int sock); +int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, int msgID, + MQTTSubscribe_options* opts, MQTTProperties* props); +int MQTTProtocol_handleSubacks(void* pack, int sock); +int MQTTProtocol_unsubscribe(Clients* client, List* topics, int msgID, MQTTProperties* props); +int MQTTProtocol_handleUnsubacks(void* pack, int sock); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTReasonCodes.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTReasonCodes.h new file mode 100644 index 0000000..2dc08ea --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTReasonCodes.h @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTREASONCODES_H) +#define MQTTREASONCODES_H + +#include "MQTTExportDeclarations.h" + +/** The MQTT V5 one byte reason code */ +enum MQTTReasonCodes { + MQTTREASONCODE_SUCCESS = 0, + MQTTREASONCODE_NORMAL_DISCONNECTION = 0, + MQTTREASONCODE_GRANTED_QOS_0 = 0, + MQTTREASONCODE_GRANTED_QOS_1 = 1, + MQTTREASONCODE_GRANTED_QOS_2 = 2, + MQTTREASONCODE_DISCONNECT_WITH_WILL_MESSAGE = 4, + MQTTREASONCODE_NO_MATCHING_SUBSCRIBERS = 16, + MQTTREASONCODE_NO_SUBSCRIPTION_FOUND = 17, + MQTTREASONCODE_CONTINUE_AUTHENTICATION = 24, + MQTTREASONCODE_RE_AUTHENTICATE = 25, + MQTTREASONCODE_UNSPECIFIED_ERROR = 128, + MQTTREASONCODE_MALFORMED_PACKET = 129, + MQTTREASONCODE_PROTOCOL_ERROR = 130, + MQTTREASONCODE_IMPLEMENTATION_SPECIFIC_ERROR = 131, + MQTTREASONCODE_UNSUPPORTED_PROTOCOL_VERSION = 132, + MQTTREASONCODE_CLIENT_IDENTIFIER_NOT_VALID = 133, + MQTTREASONCODE_BAD_USER_NAME_OR_PASSWORD = 134, + MQTTREASONCODE_NOT_AUTHORIZED = 135, + MQTTREASONCODE_SERVER_UNAVAILABLE = 136, + MQTTREASONCODE_SERVER_BUSY = 137, + MQTTREASONCODE_BANNED = 138, + MQTTREASONCODE_SERVER_SHUTTING_DOWN = 139, + MQTTREASONCODE_BAD_AUTHENTICATION_METHOD = 140, + MQTTREASONCODE_KEEP_ALIVE_TIMEOUT = 141, + MQTTREASONCODE_SESSION_TAKEN_OVER = 142, + MQTTREASONCODE_TOPIC_FILTER_INVALID = 143, + MQTTREASONCODE_TOPIC_NAME_INVALID = 144, + MQTTREASONCODE_PACKET_IDENTIFIER_IN_USE = 145, + MQTTREASONCODE_PACKET_IDENTIFIER_NOT_FOUND = 146, + MQTTREASONCODE_RECEIVE_MAXIMUM_EXCEEDED = 147, + MQTTREASONCODE_TOPIC_ALIAS_INVALID = 148, + MQTTREASONCODE_PACKET_TOO_LARGE = 149, + MQTTREASONCODE_MESSAGE_RATE_TOO_HIGH = 150, + MQTTREASONCODE_QUOTA_EXCEEDED = 151, + MQTTREASONCODE_ADMINISTRATIVE_ACTION = 152, + MQTTREASONCODE_PAYLOAD_FORMAT_INVALID = 153, + MQTTREASONCODE_RETAIN_NOT_SUPPORTED = 154, + MQTTREASONCODE_QOS_NOT_SUPPORTED = 155, + MQTTREASONCODE_USE_ANOTHER_SERVER = 156, + MQTTREASONCODE_SERVER_MOVED = 157, + MQTTREASONCODE_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158, + MQTTREASONCODE_CONNECTION_RATE_EXCEEDED = 159, + MQTTREASONCODE_MAXIMUM_CONNECT_TIME = 160, + MQTTREASONCODE_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161, + MQTTREASONCODE_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162 +}; + +/** + * Returns a printable string description of an MQTT V5 reason code. + * @param value an MQTT V5 reason code. + * @return the printable string description of the input reason code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTReasonCode_toString(enum MQTTReasonCodes value); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTSubscribeOpts.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTSubscribeOpts.h new file mode 100644 index 0000000..264e4d0 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTSubscribeOpts.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(SUBOPTS_H) +#define SUBOPTS_H + +/** The MQTT V5 subscribe options, apart from QoS which existed before V5. */ +typedef struct MQTTSubscribe_options +{ + /** The eyecatcher for this structure. Must be MQSO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0. + */ + int struct_version; + /** To not receive our own publications, set to 1. + * 0 is the original MQTT behaviour - all messages matching the subscription are received. + */ + unsigned char noLocal; + /** To keep the retain flag as on the original publish message, set to 1. + * If 0, defaults to the original MQTT behaviour where the retain flag is only set on + * publications sent by a broker if in response to a subscribe request. + */ + unsigned char retainAsPublished; + /** 0 - send retained messages at the time of the subscribe (original MQTT behaviour) + * 1 - send retained messages on subscribe only if the subscription is new + * 2 - do not send retained messages at all + */ + unsigned char retainHandling; +} MQTTSubscribe_options; + +#define MQTTSubscribe_options_initializer { {'M', 'Q', 'S', 'O'}, 0, 0, 0, 0 } + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTTime.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTTime.h new file mode 100644 index 0000000..8bd6860 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/MQTTTime.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + *******************************************************************************/ + +#if !defined(MQTTTIME_H) +#define MQTTTIME_H + +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#if WINVER >= _WIN32_WINNT_VISTA +#define START_TIME_TYPE ULONGLONG +#define START_TIME_ZERO 0 +#else +#define START_TIME_TYPE DWORD +#define START_TIME_ZERO 0 +#endif +#elif defined(AIX) +#define START_TIME_TYPE struct timespec +#define START_TIME_ZERO {0, 0} +#else +#include +#define START_TIME_TYPE struct timeval +#define START_TIME_ZERO {0, 0} +#endif + +#define ELAPSED_TIME_TYPE uint64_t +#define DIFF_TIME_TYPE int64_t + +void MQTTTime_sleep(ELAPSED_TIME_TYPE milliseconds); +START_TIME_TYPE MQTTTime_start_clock(void); +START_TIME_TYPE MQTTTime_now(void); +ELAPSED_TIME_TYPE MQTTTime_elapsed(START_TIME_TYPE milliseconds); +DIFF_TIME_TYPE MQTTTime_difftime(START_TIME_TYPE new, START_TIME_TYPE old); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Messages.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Messages.h new file mode 100644 index 0000000..58f5eae --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Messages.h @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MESSAGES_H) +#define MESSAGES_H + +#include "Log.h" + +const char* Messages_get(int, enum LOG_LEVELS); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/OsWrapper.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/OsWrapper.h new file mode 100644 index 0000000..96b629d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/OsWrapper.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016, 2017 logi.cals GmbH + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Gunter Raidl - timer support for VxWorks + * Rainer Poisel - reusability + *******************************************************************************/ + +#if !defined(OSWRAPPER_H) +#define OSWRAPPER_H + +#if defined(_WRS_KERNEL) +#include + +#define lstat stat + +typedef unsigned long useconds_t; +void usleep(useconds_t useconds); + +#define timersub(a, b, result) \ + do \ + { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) \ + { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000L; \ + } \ + } while (0) +#endif /* defined(_WRS_KERNEL) */ + +#endif /* OSWRAPPER_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/SHA1.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/SHA1.h new file mode 100644 index 0000000..3ae2f0a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/SHA1.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2018, 2019 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(SHA1_H) +#define SHA1_H + +#if defined(OPENSSL) +#include + +/** SHA-1 Digest Length */ +#define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH + +#else /* if defined(OPENSSL) */ + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +typedef struct SHA_CTX_S +{ + HCRYPTPROV hProv; + HCRYPTHASH hHash; +} SHA_CTX; +#else /* if defined(_WIN32) || defined(_WIN64) */ + +#include +typedef struct SHA_CTX_S { + uint32_t h[5]; + union { + uint32_t w[16]; + uint8_t buffer[64]; + }; + unsigned int size; + unsigned int total; +} SHA_CTX; +#endif /* else if defined(_WIN32) || defined(_WIN64) */ + +#include + +/** SHA-1 Digest Length (number of bytes in SHA1) */ +#define SHA1_DIGEST_LENGTH (160/8) + +/** + * Initializes the SHA1 hashing algorithm + * + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Update + * @see SHA1_Final + */ +int SHA1_Init(SHA_CTX *ctx); + +/** + * Updates a block to the SHA1 hash + * + * @param[in,out] ctx hashing context structure + * @param[in] data block of data to hash + * @param[in] len length of block to hash + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Update(SHA_CTX *ctx, const void *data, size_t len); + +/** + * Produce final SHA1 hash + * + * @param[out] md SHA1 hash produced (must be atleast + * @p SHA1_DIGEST_LENGTH in length) + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Final(unsigned char *md, SHA_CTX *ctx); + +#endif /* if defined(OPENSSL) */ +#endif /* SHA1_H */ + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/SSLSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/SSLSocket.h new file mode 100644 index 0000000..86273c8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/SSLSocket.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs, Allan Stockdill-Mander - initial implementation + * Ian Craggs - SNI support + * Ian Craggs - post connect checks and CApath + *******************************************************************************/ +#if !defined(SSLSOCKET_H) +#define SSLSOCKET_H + +#if defined(_WIN32) || defined(_WIN64) + #define ssl_mutex_type HANDLE +#else + #include + #include + #define ssl_mutex_type pthread_mutex_t +#endif + +#include +#include "SocketBuffer.h" +#include "Clients.h" + +#define URI_SSL "ssl://" + +/** if we should handle openssl initialization (bool_value == 1) or depend on it to be initalized externally (bool_value == 0) */ +void SSLSocket_handleOpensslInit(int bool_value); + +int SSLSocket_initialize(void); +void SSLSocket_terminate(void); +int SSLSocket_setSocketForSSL(networkHandles* net, MQTTClient_SSLOptions* opts, const char* hostname, size_t hostname_len); + +int SSLSocket_getch(SSL* ssl, int socket, char* c); +char *SSLSocket_getdata(SSL* ssl, int socket, size_t bytes, size_t* actual_len, int* rc); + +int SSLSocket_close(networkHandles* net); +int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +int SSLSocket_connect(SSL* ssl, int sock, const char* hostname, int verify, int (*cb)(const char *str, size_t len, void *u), void* u); + +int SSLSocket_getPendingRead(void); +int SSLSocket_continueWrite(pending_writes* pw); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Socket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Socket.h new file mode 100644 index 0000000..39a8158 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Socket.h @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + * Ian Craggs - async client updates + *******************************************************************************/ + +#if !defined(SOCKET_H) +#define SOCKET_H + +#include +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#include +#define MAXHOSTNAMELEN 256 +#if !defined(SSLSOCKET_H) +#undef EAGAIN +#define EAGAIN WSAEWOULDBLOCK +#undef EINTR +#define EINTR WSAEINTR +#undef EINPROGRESS +#define EINPROGRESS WSAEINPROGRESS +#undef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#undef ENOTCONN +#define ENOTCONN WSAENOTCONN +#undef ECONNRESET +#define ECONNRESET WSAECONNRESET +#undef ETIMEDOUT +#define ETIMEDOUT WAIT_TIMEOUT +#endif +#define ioctl ioctlsocket +#define socklen_t int +#else +#define INVALID_SOCKET SOCKET_ERROR +#include +#if !defined(_WRS_KERNEL) +#include +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define ULONG size_t +#endif + +#include "mutex_type.h" /* Needed for mutex_type */ + +/** socket operation completed successfully */ +#define TCPSOCKET_COMPLETE 0 +#if !defined(SOCKET_ERROR) + /** error in socket operation */ + #define SOCKET_ERROR -1 +#endif +/** must be the same as SOCKETBUFFER_INTERRUPTED */ +#define TCPSOCKET_INTERRUPTED -22 +#define SSL_FATAL -3 + +#if !defined(INET6_ADDRSTRLEN) +#define INET6_ADDRSTRLEN 46 /** only needed for gcc/cygwin on windows */ +#endif + + +#if !defined(max) +#define max(A,B) ( (A) > (B) ? (A):(B)) +#endif + +#include "LinkedList.h" + +/* + * Network write buffers for an MQTT packet + */ +typedef struct +{ + int count; /**> number of buffers/buflens/frees */ + char** buffers; /**> array of byte buffers */ + size_t* buflens; /**> array of lengths of buffers */ + int* frees; /**> array of flags indicating whether each buffer needs to be freed */ + uint8_t mask[4]; /**> websocket mask used to mask the buffer data, if any */ +} PacketBuffers; + + +/** + * Structure to hold all socket data for the module + */ +typedef struct +{ + fd_set rset, /**< socket read set (see select doc) */ + rset_saved; /**< saved socket read set */ + int maxfdp1; /**< max descriptor used +1 (again see select doc) */ + List* clientsds; /**< list of client socket descriptors */ + ListElement* cur_clientsds; /**< current client socket descriptor (iterator) */ + List* connect_pending; /**< list of sockets for which a connect is pending */ + List* write_pending; /**< list of sockets for which a write is pending */ + fd_set pending_wset; /**< socket pending write set for select */ +} Sockets; + + +void Socket_outInitialize(void); +void Socket_outTerminate(void); +int Socket_getReadySocket(int more_work, struct timeval *tp, mutex_type mutex, int* rc); +int Socket_getch(int socket, char* c); +char *Socket_getdata(int socket, size_t bytes, size_t* actual_len, int* rc); +int Socket_putdatas(int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +void Socket_close(int socket); +#if defined(__GNUC__) && defined(__linux__) +/* able to use GNU's getaddrinfo_a to make timeouts possible */ +int Socket_new(const char* addr, size_t addr_len, int port, int* socket, long timeout); +#else +int Socket_new(const char* addr, size_t addr_len, int port, int* socket); +#endif + +int Socket_noPendingWrites(int socket); +char* Socket_getpeer(int sock); + +void Socket_addPendingWrite(int socket); +void Socket_clearPendingWrite(int socket); + +typedef void Socket_writeComplete(int socket, int rc); +void Socket_setWriteCompleteCallback(Socket_writeComplete*); + +#endif /* SOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/SocketBuffer.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/SocketBuffer.h new file mode 100644 index 0000000..0fc7d6e --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/SocketBuffer.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + *******************************************************************************/ + +#if !defined(SOCKETBUFFER_H) +#define SOCKETBUFFER_H + +#if defined(_WIN32) || defined(_WIN64) +#include +#else +#include +#endif + +#if defined(OPENSSL) +#include +#endif + +#if defined(_WIN32) || defined(_WIN64) + typedef WSABUF iobuf; +#else + typedef struct iovec iobuf; +#endif + +typedef struct +{ + int socket; + unsigned int index; + size_t headerlen; + char fixed_header[5]; /**< header plus up to 4 length bytes */ + size_t buflen, /**< total length of the buffer */ + datalen; /**< current length of data in buf */ + char* buf; +} socket_queue; + +typedef struct +{ + int socket, count; + size_t total; +#if defined(OPENSSL) + SSL* ssl; +#endif + size_t bytes; + iobuf iovecs[5]; + int frees[5]; +} pending_writes; + +#define SOCKETBUFFER_COMPLETE 0 +#if !defined(SOCKET_ERROR) + #define SOCKET_ERROR -1 +#endif +#define SOCKETBUFFER_INTERRUPTED -22 /* must be the same value as TCPSOCKET_INTERRUPTED */ + +int SocketBuffer_initialize(void); +void SocketBuffer_terminate(void); +void SocketBuffer_cleanup(int socket); +char* SocketBuffer_getQueuedData(int socket, size_t bytes, size_t* actual_len); +int SocketBuffer_getQueuedChar(int socket, char* c); +void SocketBuffer_interrupted(int socket, size_t actual_len); +char* SocketBuffer_complete(int socket); +void SocketBuffer_queueChar(int socket, char c); + +#if defined(OPENSSL) +int SocketBuffer_pendingWrite(int socket, SSL* ssl, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#else +int SocketBuffer_pendingWrite(int socket, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#endif +pending_writes* SocketBuffer_getWrite(int socket); +int SocketBuffer_writeComplete(int socket); +pending_writes* SocketBuffer_updateWrite(int socket, char* topic, char* payload); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/StackTrace.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/StackTrace.h new file mode 100644 index 0000000..c4f0d43 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/StackTrace.h @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#ifndef STACKTRACE_H_ +#define STACKTRACE_H_ + +#if defined(HIGH_PERFORMANCE) +#define NOSTACKTRACE 1 +#endif + +#include +#include "Log.h" +#include "Thread.h" + +#if defined(NOSTACKTRACE) +#define FUNC_ENTRY +#define FUNC_ENTRY_NOLOG +#define FUNC_ENTRY_MED +#define FUNC_ENTRY_MAX +#define FUNC_EXIT +#define FUNC_EXIT_NOLOG +#define FUNC_EXIT_MED +#define FUNC_EXIT_MAX +#define FUNC_EXIT_RC(x) +#define FUNC_EXIT_MED_RC(x) +#define FUNC_EXIT_MAX_RC(x) +#else +#if defined(_WIN32) || defined(_WIN64) +#define inline __inline +#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM) +#else +#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM) +#endif +#endif + +void StackTrace_entry(const char* name, int line, enum LOG_LEVELS trace); +void StackTrace_exit(const char* name, int line, void* return_value, enum LOG_LEVELS trace); + +void StackTrace_printStack(FILE* dest); +char* StackTrace_get(thread_id_type, char* buf, int bufsize); + +#endif /* STACKTRACE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Thread.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Thread.h new file mode 100644 index 0000000..29903f5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Thread.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + * Ian Craggs, Allan Stockdill-Mander - async client updates + * Ian Craggs - fix for bug #420851 + * Ian Craggs - change MacOS semaphore implementation + *******************************************************************************/ + +#if !defined(THREAD_H) +#define THREAD_H + +#include "MQTTExportDeclarations.h" + +#include "MQTTClient.h" + +#include "mutex_type.h" /* Needed for mutex_type */ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define thread_type HANDLE + #define thread_id_type DWORD + #define thread_return_type DWORD + #define thread_fn LPTHREAD_START_ROUTINE + #define cond_type HANDLE + #define sem_type HANDLE + #undef ETIMEDOUT + #define ETIMEDOUT WSAETIMEDOUT +#else + #include + + #define thread_type pthread_t + #define thread_id_type pthread_t + #define thread_return_type void* + typedef thread_return_type (*thread_fn)(void*); + typedef struct { pthread_cond_t cond; pthread_mutex_t mutex; } cond_type_struct; + typedef cond_type_struct *cond_type; + #if defined(OSX) + #include + typedef dispatch_semaphore_t sem_type; + #else + #include + typedef sem_t *sem_type; + #endif + + cond_type Thread_create_cond(int*); + int Thread_signal_cond(cond_type); + int Thread_wait_cond(cond_type condvar, int timeout); + int Thread_destroy_cond(cond_type); +#endif + +LIBMQTT_API thread_type Thread_start(thread_fn, void*); + +LIBMQTT_API mutex_type Thread_create_mutex(int*); +LIBMQTT_API int Thread_lock_mutex(mutex_type); +LIBMQTT_API int Thread_unlock_mutex(mutex_type); +int Thread_destroy_mutex(mutex_type); + +LIBMQTT_API thread_id_type Thread_getid(); + +sem_type Thread_create_sem(int*); +int Thread_wait_sem(sem_type sem, int timeout); +int Thread_check_sem(sem_type sem); +int Thread_post_sem(sem_type sem); +int Thread_destroy_sem(sem_type sem); + + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Tree.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Tree.h new file mode 100644 index 0000000..dfd70ab --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/Tree.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + + +#if !defined(TREE_H) +#define TREE_H + +#include /* for size_t definition */ + +/*BE +defm defTree(T) // macro to define a tree + +def T concat Node +{ + n32 ptr T concat Node "parent" + n32 ptr T concat Node "left" + n32 ptr T concat Node "right" + n32 ptr T id2str(T) + n32 suppress "size" +} + + +def T concat Tree +{ + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + n32 dec "count" + n32 dec suppress "size" +} + +endm + +defTree(INT) +defTree(STRING) +defTree(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct NodeStruct +{ + struct NodeStruct *parent, /**< pointer to parent tree node, in case we need it */ + *child[2]; /**< pointers to child tree nodes 0 = left, 1 = right */ + void* content; /**< pointer to element content */ + size_t size; /**< size of content */ + unsigned int red : 1; +} Node; + + +/** + * Structure to hold all data for one tree + */ +typedef struct +{ + struct + { + Node *root; /**< root node pointer */ + int (*compare)(void*, void*, int); /**< comparison function */ + } index[2]; + int indexes, /**< no of indexes into tree */ + count; /**< no of items */ + size_t size; /**< heap storage used */ + unsigned int heap_tracking : 1; /**< switch on heap tracking for this tree? */ + unsigned int allow_duplicates : 1; /**< switch to allow duplicate entries */ +} Tree; + + +Tree* TreeInitialize(int(*compare)(void*, void*, int)); +void TreeInitializeNoMalloc(Tree* aTree, int(*compare)(void*, void*, int)); +void TreeAddIndex(Tree* aTree, int(*compare)(void*, void*, int)); + +void* TreeAdd(Tree* aTree, void* content, size_t size); + +void* TreeRemove(Tree* aTree, void* content); + +void* TreeRemoveKey(Tree* aTree, void* key); +void* TreeRemoveKeyIndex(Tree* aTree, void* key, int index); + +void* TreeRemoveNodeIndex(Tree* aTree, Node* aNode, int index); + +void TreeFree(Tree* aTree); + +Node* TreeFind(Tree* aTree, void* key); +Node* TreeFindIndex(Tree* aTree, void* key, int index); + +Node* TreeNextElement(Tree* aTree, Node* curnode); + +int TreeIntCompare(void* a, void* b, int); +int TreePtrCompare(void* a, void* b, int); +int TreeStringCompare(void* a, void* b, int); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/VersionInfo.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/VersionInfo.h new file mode 100644 index 0000000..b3b3e78 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/VersionInfo.h @@ -0,0 +1,7 @@ +#ifndef VERSIONINFO_H +#define VERSIONINFO_H + +#define BUILD_TIMESTAMP "2021-02-11 12:10" +#define CLIENT_VERSION "1.3.8" + +#endif /* VERSIONINFO_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/WebSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/WebSocket.h new file mode 100644 index 0000000..e9f5765 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/WebSocket.h @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2018, 2020 Wind River Systems, Inc. and others. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(WEBSOCKET_H) +#define WEBSOCKET_H + +#include "MQTTPacket.h" + +/** + * WebSocket op codes + * @{ + */ +#define WebSocket_OP_CONTINUE 0x0 /* 0000 - continue frame */ +#define WebSocket_OP_TEXT 0x1 /* 0001 - text frame */ +#define WebSocket_OP_BINARY 0x2 /* 0010 - binary frame */ +#define WebSocket_OP_CLOSE 0x8 /* 1000 - close frame */ +#define WebSocket_OP_PING 0x9 /* 1001 - ping frame */ +#define WebSocket_OP_PONG 0xA /* 1010 - pong frame */ +/** @} */ + +/** + * Various close status codes + * @{ + */ +#define WebSocket_CLOSE_NORMAL 1000 +#define WebSocket_CLOSE_GOING_AWAY 1001 +#define WebSocket_CLOSE_PROTOCOL_ERROR 1002 +#define WebSocket_CLOSE_UNKNOWN_DATA 1003 +#define WebSocket_CLOSE_RESERVED 1004 +#define WebSocket_CLOSE_NO_STATUS_CODE 1005 /* reserved: not to be used */ +#define WebSocket_CLOSE_ABNORMAL 1006 /* reserved: not to be used */ +#define WebSocket_CLOSE_BAD_DATA 1007 +#define WebSocket_CLOSE_POLICY 1008 +#define WebSocket_CLOSE_MSG_TOO_BIG 1009 +#define WebSocket_CLOSE_NO_EXTENSION 1010 +#define WebScoket_CLOSE_UNEXPECTED 1011 +#define WebSocket_CLOSE_TLS_FAIL 1015 /* reserved: not be used */ +/** @} */ + +/* closes a websocket connection */ +void WebSocket_close(networkHandles *net, int status_code, const char *reason); + +/* sends upgrade request */ +int WebSocket_connect(networkHandles *net, const char *uri); + +/* obtain data from network socket */ +int WebSocket_getch(networkHandles *net, char* c); +char *WebSocket_getdata(networkHandles *net, size_t bytes, size_t* actual_len); +size_t WebSocket_framePos(); +void WebSocket_framePosSeekTo(size_t); + +/* send data out, in websocket format only if required */ +int WebSocket_putdatas(networkHandles* net, char** buf0, size_t* buf0len, PacketBuffers* bufs); + +/* releases any resources used by the websocket system */ +void WebSocket_terminate(void); + +/* handles websocket upgrade request */ +int WebSocket_upgrade(networkHandles *net); + +/* Notify the IP address and port of the endpoint to proxy, and wait connection to endpoint */ +int WebSocket_proxy_connect( networkHandles *net, int ssl, const char *hostname); + +#endif /* WEBSOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/mutex_type.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/mutex_type.h new file mode 100644 index 0000000..1e4b9e5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/mutex_type.h @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + *******************************************************************************/ +#if !defined(_MUTEX_TYPE_H_) +#define _MUTEX_TYPE_H_ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define mutex_type HANDLE +#else + #include + #define mutex_type pthread_mutex_t* +#endif + +#endif /* _MUTEX_TYPE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/utf-8.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/utf-8.h new file mode 100644 index 0000000..a7a4270 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/include/utf-8.h @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(UTF8_H) +#define UTF8_H + +int UTF8_validate(int len, const char *data); +int UTF8_validateString(const char* string); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libAR.a new file mode 100644 index 0000000..41d916b Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libOpenSSL_s.a new file mode 100644 index 0000000..2434b46 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libPahoMQTT_s.a new file mode 100644 index 0000000..a2f8f24 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libar_posix_s.a new file mode 100644 index 0000000..90cf078 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.63.0/SG4/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/Binary.lby b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/Binary.lby new file mode 100644 index 0000000..59b625d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/Binary.lby @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libAR.a new file mode 100644 index 0000000..235f5d6 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libOpenSSL_s.a new file mode 100644 index 0000000..a6bba1f Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libPahoMQTT_s.a new file mode 100644 index 0000000..befa486 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libar_posix_s.a new file mode 100644 index 0000000..15d300a Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/Arm/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Base64.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Base64.h new file mode 100644 index 0000000..7022ce8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Base64.h @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2018 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(BASE64_H) +#define BASE64_H + +/** type for size of a buffer, it saves passing around @p size_t (unsigned long long or unsigned long int) */ +typedef unsigned int b64_size_t; +/** type for raw base64 data */ +typedef unsigned char b64_data_t; + +/** + * Decodes base64 data + * + * @param[out] out decoded data + * @param[in] out_len length of output buffer + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the amount of data decoded + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_decode( b64_data_t *out, b64_size_t out_len, + const char *in, b64_size_t in_len ); + +/** + * Size of buffer required to decode base64 data + * + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the decoded string would require + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_decodeLength( const char *in, b64_size_t in_len ); + +/** + * Encodes base64 data + * + * @param[out] out encode base64 string + * @param[in] out_len length of output buffer + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the amount of data encoded + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_encode( char *out, b64_size_t out_len, + const b64_data_t *in, b64_size_t in_len ); + +/** + * Size of buffer required to encode base64 data + * + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the encoded string would require + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_encodeLength( const b64_data_t *in, b64_size_t in_len ); + +#endif /* BASE64_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Clients.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Clients.h new file mode 100644 index 0000000..a3ddb1f --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Clients.h @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - add SSL support + * Ian Craggs - fix for bug 413429 - connectionLost not called + * Ian Craggs - change will payload to binary + * Ian Craggs - password to binary + * Ian Craggs - MQTT 5 support + *******************************************************************************/ + +#if !defined(CLIENTS_H) +#define CLIENTS_H + +#include +#include "MQTTTime.h" +#if defined(OPENSSL) +#if defined(_WIN32) || defined(_WIN64) +#include +#endif +#include +#endif +#include "MQTTClient.h" +#include "LinkedList.h" +#include "MQTTClientPersistence.h" + +/** + * Stored publication data to minimize copying + */ +typedef struct +{ + char *topic; + int topiclen; + char* payload; + int payloadlen; + int refcount; + uint8_t mask[4]; +} Publications; + +/** + * Client publication message data + */ +typedef struct +{ + int qos; + int retain; + int msgid; + int MQTTVersion; + MQTTProperties properties; + Publications *publish; + START_TIME_TYPE lastTouch; /**> used for retry and expiry */ + char nextMessageType; /**> PUBREC, PUBREL, PUBCOMP */ + int len; /**> length of the whole structure+data */ +} Messages; + +/** + * Client will message data + */ +typedef struct +{ + char *topic; + int payloadlen; + void *payload; + int retained; + int qos; +} willMessages; + +typedef struct +{ + int socket; + START_TIME_TYPE lastSent; + START_TIME_TYPE lastReceived; + START_TIME_TYPE lastPing; +#if defined(OPENSSL) + SSL* ssl; + SSL_CTX* ctx; + char *https_proxy; + char *https_proxy_auth; +#endif + char *http_proxy; + char *http_proxy_auth; + int websocket; /**< socket has been upgraded to use web sockets */ + char *websocket_key; + const MQTTClient_nameValue* httpHeaders; +} networkHandles; + + +/* connection states */ +/** no connection in progress, see connected value */ +#define NOT_IN_PROGRESS 0x0 +/** TCP connection in progress */ +#define TCP_IN_PROGRESS 0x1 +/** SSL connection in progress */ +#define SSL_IN_PROGRESS 0x2 +/** Websocket connection in progress */ +#define WEBSOCKET_IN_PROGRESS 0x3 +/** TCP completed, waiting for MQTT ACK */ +#define WAIT_FOR_CONNACK 0x4 +/** Proxy connection in progress */ +#define PROXY_CONNECT_IN_PROGRESS 0x5 +/** Disconnecting */ +#define DISCONNECTING -2 + +/** + * Data related to one client + */ +typedef struct +{ + char* clientID; /**< the string id of the client */ + const char* username; /**< MQTT v3.1 user name */ + int passwordlen; /**< MQTT password length */ + const void* password; /**< MQTT v3.1 binary password */ + unsigned int cleansession : 1; /**< MQTT V3 clean session flag */ + unsigned int cleanstart : 1; /**< MQTT V5 clean start flag */ + unsigned int connected : 1; /**< whether it is currently connected */ + unsigned int good : 1; /**< if we have an error on the socket we turn this off */ + unsigned int ping_outstanding : 1; + signed int connect_state : 4; + networkHandles net; /**< network info for this client */ + int msgID; /**< the MQTT message id */ + int keepAliveInterval; /**< the MQTT keep alive interval */ + int retryInterval; + int maxInflightMessages; /**< the max number of inflight outbound messages we allow */ + willMessages* will; /**< the MQTT will message, if any */ + List* inboundMsgs; /**< inbound in flight messages */ + List* outboundMsgs; /**< outbound in flight messages */ + List* messageQueue; /**< inbound complete but undelivered messages */ + unsigned int qentry_seqno; + void* phandle; /**< the persistence handle */ + MQTTClient_persistence* persistence; /**< a persistence implementation */ + MQTTPersistence_beforeWrite* beforeWrite; /**< persistence write callback */ + MQTTPersistence_afterRead* afterRead; /**< persistence read callback */ + void* beforeWrite_context; /**< context to be used with the persistence beforeWrite callbacks */ + void* afterRead_context; /**< context to be used with the persistence afterRead callback */ + void* context; /**< calling context - used when calling disconnect_internal */ + int MQTTVersion; /**< the version of MQTT being used, 3, 4 or 5 */ + int sessionExpiry; /**< MQTT 5 session expiry */ + char* httpProxy; /**< HTTP proxy for websockets */ + char* httpsProxy; /**< HTTPS proxy for websockets */ +#if defined(OPENSSL) + MQTTClient_SSLOptions *sslopts; /**< the SSL/TLS connect options */ + SSL_SESSION* session; /**< SSL session pointer for fast handhake */ +#endif +} Clients; + +int clientIDCompare(void* a, void* b); +int clientSocketCompare(void* a, void* b); + +/** + * Configuration data related to all clients + */ +typedef struct +{ + const char* version; + List* clients; +} ClientStates; + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Heap.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Heap.h new file mode 100644 index 0000000..f89a760 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Heap.h @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - use tree data structure instead of list + *******************************************************************************/ + + +#if !defined(HEAP_H) +#define HEAP_H + +#if defined(HIGH_PERFORMANCE) +#define NO_HEAP_TRACKING 1 +#endif + +#define PAHO_MEMORY_ERROR -99 + +#include "MQTTExportDeclarations.h" + +#include +#include + +#if !defined(NO_HEAP_TRACKING) + +#if !defined(TREE_C) +/** + * redefines malloc to use "mymalloc" so that heap allocation can be tracked + * @param x the size of the item to be allocated + * @return the pointer to the item allocated, or NULL + */ +#define malloc(x) mymalloc(__FILE__, __LINE__, x) + +/** + * redefines realloc to use "myrealloc" so that heap allocation can be tracked + * @param a the heap item to be reallocated + * @param b the new size of the item + * @return the new pointer to the heap item + */ +#define realloc(a, b) myrealloc(__FILE__, __LINE__, a, b) + +/** + * redefines free to use "myfree" so that heap allocation can be tracked + * @param x the size of the item to be freed + */ +#define free(x) myfree(__FILE__, __LINE__, x) + +#endif + +/** + * Information about the state of the heap. + */ +typedef struct +{ + size_t current_size; /**< current size of the heap in bytes */ + size_t max_size; /**< max size the heap has reached in bytes */ +} heap_info; + +#if defined(__cplusplus) + extern "C" { +#endif + +void* mymalloc(char*, int, size_t size); +void* myrealloc(char*, int, void* p, size_t size); +void myfree(char*, int, void* p); + +void Heap_scan(FILE* file); +int Heap_initialize(void); +void Heap_terminate(void); +LIBMQTT_API heap_info* Heap_get_info(void); +int HeapDump(FILE* file); +int HeapDumpString(FILE* file, char* str); +void* Heap_findItem(void* p); +void Heap_unlink(char* file, int line, void* p); +#ifdef __cplusplus + } +#endif + +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/LinkedList.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/LinkedList.h new file mode 100644 index 0000000..e390012 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/LinkedList.h @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + * Ian Craggs - change size types from int to size_t + *******************************************************************************/ + +#if !defined(LINKEDLIST_H) +#define LINKEDLIST_H + +#include /* for size_t definition */ + +/*BE +defm defList(T) + +def T concat Item +{ + at 4 + n32 ptr T concat Item suppress "next" + at 0 + n32 ptr T concat Item suppress "prev" + at 8 + n32 ptr T id2str(T) +} + +def T concat List +{ + n32 ptr T concat Item suppress "first" + n32 ptr T concat Item suppress "last" + n32 ptr T concat Item suppress "current" + n32 dec "count" + n32 suppress "size" +} +endm + +defList(INT) +defList(STRING) +defList(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct ListElementStruct +{ + struct ListElementStruct *prev, /**< pointer to previous list element */ + *next; /**< pointer to next list element */ + void* content; /**< pointer to element content */ +} ListElement; + + +/** + * Structure to hold all data for one list + */ +typedef struct +{ + ListElement *first, /**< first element in the list */ + *last, /**< last element in the list */ + *current; /**< current element in the list, for iteration */ + int count; /**< no of items */ + size_t size; /**< heap storage used */ +} List; + +void ListZero(List*); +List* ListInitialize(void); + +ListElement* ListAppend(List* aList, void* content, size_t size); +void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, size_t size); +ListElement* ListInsert(List* aList, void* content, size_t size, ListElement* index); + +int ListRemove(List* aList, void* content); +int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*)); +void* ListDetachHead(List* aList); +int ListRemoveHead(List* aList); +void* ListPopTail(List* aList); + +int ListDetach(List* aList, void* content); +int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*)); + +void ListFree(List* aList); +void ListEmpty(List* aList); +void ListFreeNoContent(List* aList); + +ListElement* ListNextElement(List* aList, ListElement** pos); +ListElement* ListPrevElement(List* aList, ListElement** pos); + +ListElement* ListFind(List* aList, void* content); +ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*)); + +int intcompare(void* a, void* b); +int stringcompare(void* a, void* b); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Log.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Log.h new file mode 100644 index 0000000..102e31d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Log.h @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + *******************************************************************************/ + +#if !defined(LOG_H) +#define LOG_H + +/*BE +map LOG_LEVELS +{ + "TRACE_MAXIMUM" 1 + "TRACE_MEDIUM" 2 + "TRACE_MINIMUM" 3 + "TRACE_PROTOCOL" 4 + + "ERROR" 5 + "SEVERE" 6 + "FATAL" 7 +} +BE*/ + +enum LOG_LEVELS { + INVALID_LEVEL = -1, + TRACE_MAXIMUM = 1, + TRACE_MEDIUM, + TRACE_MINIMUM, + TRACE_PROTOCOL, + LOG_ERROR, + LOG_SEVERE, + LOG_FATAL, +}; + + +/*BE +def trace_settings_type +{ + n32 map LOG_LEVELS "trace_level" + n32 dec "max_trace_entries" + n32 dec "trace_output_level" +} +BE*/ +typedef struct +{ + enum LOG_LEVELS trace_level; /**< trace level */ + int max_trace_entries; /**< max no of entries in the trace buffer */ + enum LOG_LEVELS trace_output_level; /**< trace level to output to destination */ +} trace_settings_type; + +extern trace_settings_type trace_settings; + +#define LOG_PROTOCOL TRACE_PROTOCOL +#define TRACE_MAX TRACE_MAXIMUM +#define TRACE_MIN TRACE_MINIMUM +#define TRACE_MED TRACE_MEDIUM + +typedef struct +{ + const char* name; + const char* value; +} Log_nameValue; + +int Log_initialize(Log_nameValue*); +void Log_terminate(void); + +void Log(enum LOG_LEVELS, int, const char *, ...); +void Log_stackTrace(enum LOG_LEVELS, int, int, int, const char*, int, int*); + +typedef void Log_traceCallback(enum LOG_LEVELS level, const char *message); +void Log_setTraceCallback(Log_traceCallback* callback); +void Log_setTraceLevel(enum LOG_LEVELS level); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTAsync.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTAsync.h new file mode 100644 index 0000000..f728ba5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTAsync.h @@ -0,0 +1,2345 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation + * Ian Craggs, Allan Stockdill-Mander - SSL connections + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - fix for bug 444103 - success/failure callbacks not invoked + * Ian Craggs - automatic reconnect and offline buffering (send while disconnected) + * Ian Craggs - binary will message + * Ian Craggs - binary password + * Ian Craggs - remove const on eyecatchers #168 + * Ian Craggs - MQTT 5.0 + *******************************************************************************/ + +/********************************************************************/ + +/** + * @cond MQTTAsync_main + * @mainpage Asynchronous MQTT client library for C + * + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An Asynchronous MQTT client library for C. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the Asynchronous MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions
  • + *
  • Connect the client to an MQTT server
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref publish
  • + *
  • @ref subscribe
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
  • @ref auto_reconnect
  • + *
  • @ref offline_publish
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTASYNC_H) +#define MQTTASYNC_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTASYNC_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTASYNC_FAILURE -1 + +/* error code -2 is MQTTAsync_PERSISTENCE_ERROR */ + +#define MQTTASYNC_PERSISTENCE_ERROR -2 + +/** + * Return code: The client is disconnected. + */ +#define MQTTASYNC_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTASYNC_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTASYNC_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTASYNC_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTASYNC_BAD_STRUCTURE -8 +/** + * Return code: A qos parameter is not 0, 1 or 2 + */ +#define MQTTASYNC_BAD_QOS -9 +/** + * Return code: All 65535 MQTT msgids are being used + */ +#define MQTTASYNC_NO_MORE_MSGIDS -10 +/** + * Return code: the request is being discarded when not complete + */ +#define MQTTASYNC_OPERATION_INCOMPLETE -11 +/** + * Return code: no more messages can be buffered + */ +#define MQTTASYNC_MAX_BUFFERED_MESSAGES -12 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTASYNC_SSL_NOT_SUPPORTED -13 + /** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if the TLS version of the library + * is linked with. + */ +#define MQTTASYNC_BAD_PROTOCOL -14 + /** + * Return code: don't use options for another version of MQTT + */ + #define MQTTASYNC_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the client's version of MQTT + */ + #define MQTTASYNC_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic + */ + #define MQTTASYNC_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 +/** + * MQTT version to connect with: 5 + */ +#define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTAsync_init_options; + +#define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt (0) + */ +LIBMQTT_API void MQTTAsync_global_init(MQTTAsync_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTAsync_create(). + */ +typedef void* MQTTAsync; +/** + * A value representing an MQTT message. A token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTAsync_publish(), + * MQTTAsync_publishMessage(), + * MQTTAsync_deliveryComplete(), and + * MQTTAsync_getPendingTokens()). + */ +typedef int MQTTAsync_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTAsync_publishMessage(), + * MQTTAsync_publish(), MQTTAsync_receive(), MQTTAsync_freeMessage() + * and MQTTAsync_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. This is an output parameter only. + */ + int dup; + /** The message identifier is reserved for internal use by the + * MQTT client and server. It is an output parameter only - writing + * to it will serve no purpose. It contains the MQTT message id of + * an incoming publish message. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTAsync_message; + +#define MQTTAsync_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTAsync_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTAsync_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTAsync_freeMessage must be called. + * To free the topic name storage, ::MQTTAsync_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTAsync_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTAsync_messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages to the server. The function is + * registered with the client library by passing it as an argument to MQTTAsync_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTAsync_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param token The ::MQTTAsync_token associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the tokens returned from calls to + * MQTTAsync_send() and MQTTAsync_sendMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTAsync_deliveryComplete(void* context, MQTTAsync_token token); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTAsync_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connectionLost(void* context, char* cause); + + +/** + * This is a callback function, which will be called when the client + * library successfully connects. This is superfluous when the connection + * is made in response to a MQTTAsync_connect call, because the onSuccess + * callback can be used. It is intended for use when automatic reconnect + * is enabled, so that when a reconnection attempt succeeds in the background, + * the application is notified and can take any required actions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connected(void* context, char* cause); + +/** + * This is a callback function, which will be called when the client + * library receives a disconnect packet. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param properties the properties in the disconnect packet. + * @param properties the reason code from the disconnect packet + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTAsync_disconnected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDisconnected(MQTTAsync handle, void* context, MQTTAsync_disconnected* co); + +/** The connect options that can be updated before an automatic reconnect. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQCD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name parameter. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + const char* username; + /** + * The password parameter of the MQTT authentication. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; +} MQTTAsync_connectData; + +#define MQTTAsync_connectData_initializer {{'M', 'Q', 'C', 'D'}, 0, NULL, {0, NULL}} + +/** + * This is a callback function which will allow the client application to update the + * connection data. + * @param data The connection data which can be modified by the application. + * @return Return a non-zero value to update the connect data, zero to keep the same data. + */ +typedef int MQTTAsync_updateConnectOptions(void* context, MQTTAsync_connectData* data); + +/** + * Sets the MQTTAsync_updateConnectOptions() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_updateConnectOptions() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setUpdateConnectOptions(MQTTAsync handle, void* context, MQTTAsync_updateConnectOptions* co); + +/** + * Sets the MQTTPersistence_beforeWrite() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setBeforePersistenceWrite(MQTTAsync handle, void* context, MQTTPersistence_beforeWrite* co); + + +/** + * Sets the MQTTPersistence_afterRead() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setAfterPersistenceRead(MQTTAsync handle, void* context, MQTTPersistence_afterRead* co); + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** A numeric code identifying the error. */ + int code; + /** Optional text explaining the error. Can be NULL. */ + const char *message; +} MQTTAsync_failureData; + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQFD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** The MQTT reason code returned. */ + enum MQTTReasonCodes reasonCode; + /** The MQTT properties on the ack, if any. */ + MQTTProperties properties; + /** A numeric code identifying the MQTT client library error. */ + int code; + /** Optional further text explaining the error. Can be NULL. */ + const char *message; + /** Packet type on which the failure occurred - used for publish QoS 1/2 exchanges*/ + int packet_type; +} MQTTAsync_failureData5; + +#define MQTTAsync_failureData5_initializer {{'M', 'Q', 'F', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, 0, NULL} + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribe, the granted QoS of the subscription returned by the server. + * Also for subscribeMany, if only 1 subscription was requested. */ + int qos; + /** For subscribeMany, if more than one subscription was requested, + * the list of granted QoSs of the subscriptions returned by the server. */ + int* qosList; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + } alt; +} MQTTAsync_successData; + + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + char struct_id[4]; /**< The eyecatcher for this structure. Will be MQSD. */ + int struct_version; /**< The version number of this structure. Will be 0 */ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + enum MQTTReasonCodes reasonCode; /**< MQTT V5 reason code returned */ + MQTTProperties properties; /**< MQTT V5 properties returned, if any */ + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } sub; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + /** For unsubscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } unsub; + } alt; +} MQTTAsync_successData5; + +#define MQTTAsync_successData5_initializer {{'M', 'Q', 'S', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer} + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onSuccess. + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess5(void* context, MQTTAsync_successData5* response); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure(void* context, MQTTAsync_failureData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onFailure. + * The application must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure5(void* context, MQTTAsync_failureData5* response); + +/** Structure to define call options. For MQTT 5.0 there is input data as well as that + * describing the response method. So there is now also a synonym ::MQTTAsync_callOptions + * to better reflect the use. This responseOptions name is kept for backward + * compatibility. + */ +typedef struct MQTTAsync_responseOptions +{ + /** The eyecatcher for this structure. Must be MQTR */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * if 0, no MQTTV5 options */ + int struct_version; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the API call fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * A token is returned from the call. It can be used to track + * the state of this request, both in the callbacks and in future calls + * such as ::MQTTAsync_waitForCompletion. + */ + MQTTAsync_token token; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /* + * MQTT V5 subscribe options, when used with subscribe only. + */ + MQTTSubscribe_options subscribeOptions; + /* + * MQTT V5 subscribe option count, when used with subscribeMany only. + * The number of entries in the subscribe_options_list array. + */ + int subscribeOptionsCount; + /* + * MQTT V5 subscribe option array, when used with subscribeMany only. + */ + MQTTSubscribe_options* subscribeOptionsList; +} MQTTAsync_responseOptions; + +#define MQTTAsync_responseOptions_initializer { {'M', 'Q', 'T', 'R'}, 1, NULL, NULL, 0, 0, NULL, NULL, MQTTProperties_initializer, MQTTSubscribe_options_initializer, 0, NULL} + +/** A synonym for responseOptions to better reflect its usage since MQTT 5.0 */ +typedef struct MQTTAsync_responseOptions MQTTAsync_callOptions; +#define MQTTAsync_callOptions_initializer MQTTAsync_responseOptions_initializer + +/** + * This function sets the global callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. If this callback is not set, an error will be returned. + * You must set this callback because otherwise there would be + * no way to deliver any incoming messages. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl, + MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc); + +/** + * This function sets the callback function for a connection lost event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed the callback functions to provide + * access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ + +LIBMQTT_API int MQTTAsync_setConnectionLostCallback(MQTTAsync handle, void* context, + MQTTAsync_connectionLost* cl); + +/** + * This function sets the callback function for a message arrived event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. You can set this to NULL if your application doesn't handle + * receipt of messages. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setMessageArrivedCallback(MQTTAsync handle, void* context, + MQTTAsync_messageArrived* ma); + +/** + * This function sets the callback function for a delivery complete event + * for a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDeliveryCompleteCallback(MQTTAsync handle, void* context, + MQTTAsync_deliveryComplete* dc); + +/** + * Sets the MQTTAsync_connected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co); + + +/** + * Reconnects a client with the previously used connect options. Connect + * must have previously been called for this to work. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_reconnect(MQTTAsync handle); + + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTAsync_persistence). See also MQTTAsync_destroy(). + * @param handle A pointer to an ::MQTTAsync handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of + * the library is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTASYNC_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTAsync_create(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTAsync_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2 or 3 + * 0 means no MQTTVersion + * 1 means no allowDisconnectedSendAtAnyTime, deleteOldestMessages, restoreMessages + * 2 means no persistQoS0 + */ + int struct_version; + /** Whether to allow messages to be sent when the client library is not connected. */ + int sendWhileDisconnected; + /** The maximum number of messages allowed to be buffered while not connected. */ + int maxBufferedMessages; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; + /** + * Allow sending of messages while disconnected before a first successful connect. + */ + int allowDisconnectedSendAtAnyTime; + /* + * When the maximum number of buffered messages is reached, delete the oldest rather than the newest. + */ + int deleteOldestMessages; + /* + * Restore messages from persistence on create - or clear it. + */ + int restoreMessages; + /* + * Persist QoS0 publish commands - an option to not persist them. + */ + int persistQoS0; +} MQTTAsync_createOptions; + +#define MQTTAsync_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_DEFAULT, 0, 0, 1, 1} + +#define MQTTAsync_createOptions_initializer5 { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_5, 0, 0, 1, 1} + + +LIBMQTT_API int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTAsync_createOptions* options); + +/** + * MQTTAsync_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTAsync_willOptions + * structure is passed in the MQTTAsync_connectOptions structure used in the + * MQTTAsync_connect() call that connects the client to the server. The pointer + * to MQTTAsync_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 indicates no binary will message support + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTAsync_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTAsync_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTAsync_willOptions; + +#define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTAsync_SSLOptions; + +#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** Utility structure where name/value pairs are needed */ +typedef struct +{ + const char* name; /**< name string */ + const char* value; /**< value string */ +} MQTTAsync_nameValue; + +/** + * MQTTAsync_connectOptions defines several settings that control the way the + * client connects to an MQTT server. Default values are set in + * MQTTAsync_connectOptions_initializer. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3 4 5 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no automatic reconnect options + * 4 signifies no binary password option (just string) + * 5 signifies no MQTTV5 properties + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + * Set to 0 if you do not want any keep alive processing. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTAsync_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This controls how many messages can be in-flight simultaneously. + */ + int maxInflight; + /** + * This is a pointer to an MQTTAsync_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTAsync_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTAsync_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTAsync_SSLOptions* ssl; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * The number of entries in the serverURIs array. + */ + int serverURIcount; + /** + * An array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a domain name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + */ + int MQTTVersion; + /** + * Reconnect automatically in the case of a connection being lost? + */ + int automaticReconnect; + /** + * Minimum retry interval in seconds. Doubled on each failed retry. + */ + int minRetryInterval; + /** + * Maximum retry interval in seconds. The doubling stops here on failed retries. + */ + int maxRetryInterval; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * MQTT V5 properties for connect + */ + MQTTProperties *connectProperties; + /** + * MQTT V5 properties for the will message in the connect + */ + MQTTProperties *willProperties; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * HTTP headers for websockets + */ + const MQTTAsync_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTAsync_connectOptions; + + +#define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + + +/** + * This function attempts to connect a previously-created client (see + * MQTTAsync_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTAsync_setCallbacks() prior to MQTTAsync_connect(). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options A pointer to a valid MQTTAsync_connectOptions + * structure. + * @return ::MQTTASYNC_SUCCESS if the client connect request was accepted. + * If the client was unable to connect to the server, an error code is + * returned via the onFailure callback, if set. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options); + +/** Options for the ::MQTTAsync_disconnect call */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTD. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. 0 signifies no V5 properties */ + int struct_version; + /** + * The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + */ + int timeout; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /** + * Reason code for MQTTV5 disconnect + */ + enum MQTTReasonCodes reasonCode; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; +} MQTTAsync_disconnectOptions; + +#define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 0, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +#define MQTTAsync_disconnectOptions_initializer5 { {'M', 'Q', 'T', 'D'}, 1, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTAsync_connectOptions.cleansession and MQTTAsync_connect()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions* options); + + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTAsync_isConnected(MQTTAsync handle); + + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTAsync_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTAsync_subscribe(MQTTAsync handle, const char* topic, int qos, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTAsync_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char* const* topic, const int* qos, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTAsync_unsubscribe(MQTTAsync handle, const char* topic, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const* topic, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to publish a message to a given topic (see also + * ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * This is optional and can be set to NULL. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_send(MQTTAsync handle, const char* destinationName, int payloadlen, const void* payload, int qos, + int retained, MQTTAsync_responseOptions* response); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTAsync_publish()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param msg A pointer to a valid MQTTAsync_message structure containing + * the payload and attributes of the message to be published. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_sendMessage(MQTTAsync handle, const char* destinationName, const MQTTAsync_message* msg, MQTTAsync_responseOptions* response); + + +/** + * This function sets a pointer to an array of tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param tokens The address of a pointer to an ::MQTTAsync_token. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTASYNC_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens); + +/** + * Tests whether a request corresponding to a token is complete. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @return 1 if the request has been completed, 0 if not. + */ +#define MQTTASYNC_TRUE 1 +LIBMQTT_API int MQTTAsync_isComplete(MQTTAsync handle, MQTTAsync_token token); + + +/** + * Waits for a request corresponding to a token to complete. This only works for + * messages with QoS greater than 0. A QoS 0 message has no MQTT token. + * This function will always return ::MQTTASYNC_SUCCESS for a QoS 0 message. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @param timeout the maximum time to wait for completion, in milliseconds + * @return ::MQTTASYNC_SUCCESS if the request has been completed in the time allocated, + * ::MQTTASYNC_FAILURE or ::MQTTASYNC_DISCONNECTED if not. + */ +LIBMQTT_API int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token token, unsigned long timeout); + + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTAsync_free() library function. + * @param msg The address of a pointer to the ::MQTTAsync_message structure + * to be freed. + */ +LIBMQTT_API void MQTTAsync_freeMessage(MQTTAsync_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTAsync_free(void* ptr); + +/** + * This function is used to allocate memory to be used or freed by the MQTT C client library, + * especially the data in the ::MQTTPersistence_afterRead and ::MQTTPersistence_beforeWrite + * callbacks. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. + * @param size The size of the memory to be allocated. + */ +LIBMQTT_API void* MQTTAsync_malloc(size_t size); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTAsync_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTAsync + * structure to be freed. + */ +LIBMQTT_API void MQTTAsync_destroy(MQTTAsync* handle); + + + +enum MQTTASYNC_TRACE_LEVELS +{ + MQTTASYNC_TRACE_MAXIMUM = 1, + MQTTASYNC_TRACE_MEDIUM, + MQTTASYNC_TRACE_MINIMUM, + MQTTASYNC_TRACE_PROTOCOL, + MQTTASYNC_TRACE_ERROR, + MQTTASYNC_TRACE_SEVERE, + MQTTASYNC_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTAsync_setTraceLevel(enum MQTTASYNC_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTAsync_traceCallback(enum MQTTASYNC_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTAsync_setTraceCallback(MQTTAsync_traceCallback* callback); + +/** + * This function returns version information about the library. + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void); + +/** + * Returns a pointer to a string representation of the error code, or NULL. + * Do not free after use. Returns NULL if the error code is unknown. + * @param code the MQTTASYNC_ return code. + * @return a static string representation of the error code. + */ +LIBMQTT_API const char* MQTTAsync_strerror(int code); + + +/*! + * @cond MQTTAsync_main + * @page async Threading + * The client application runs on several threads. + * Processing of handshaking and maintaining + * the network connection is performed in the background. + * This API is thread safe: functions may be called by multiple application + * threads. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(), + * MQTTAsync_connectionLost() and MQTTAsync_deliveryComplete()). + * In addition, some functions allow success and failure callbacks to be set + * for individual requests, in the ::MQTTAsync_responseOptions structure. Applications + * can be written as a chain of callback functions. + * + * @page callbacks Callbacks + * Any function from this API may be used within a callback. It is not advisable to + * use ::MQTTAsync_waitForCompletion within a callback, however, as it is the only + * API call that may take some time to complete, which may cause unpredictable + * behaviour. All the other API calls are intended to complete quickly, starting + * a request in the background, with success or failure notified by other callbacks. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * A log message will be written to highlight the issue, but it is up + * to the application to protect against this situation. + * + * @page auto_reconnect Automatic Reconnect + * The ability for the client library to reconnect automatically in the event + * of a connection failure was added in 1.1. The connection lost callback + * allows a flexible response to the loss of a connection, so almost any + * behaviour can be implemented in that way. Automatic reconnect does have the + * advantage of being a little simpler to use. + * + * To switch on automatic reconnect, the connect options field + * automaticReconnect should be set to non-zero. The minimum and maximum times + * before the next connection attempt can also be set, the defaults being 1 and + * 60 seconds. At each failure to reconnect, the retry interval is doubled until + * the maximum value is reached, and there it stays until the connection is + * successfully re-established whereupon it is reset. + * + * When a reconnection attempt is successful, the ::MQTTAsync_connected callback + * function is invoked, if set by calling ::MQTTAsync_setConnected. This allows + * the application to take any actions needed, such as amending subscriptions. + * + * @page offline_publish Publish While Disconnected + * This feature was not originally available because with persistence enabled, + * messages could be stored locally without ever knowing if they could be sent. + * The client application could have created the client with an erroneous broker + * address or port for instance. + * + * To enable messages to be published when the application is disconnected + * ::MQTTAsync_createWithOptions must be used instead of ::MQTTAsync_create to + * create the client object. The ::MQTTAsync_createOptions field sendWhileDisconnected + * must be set to non-zero, and the maxBufferedMessages field set as required - + * the default being 100. + * + * ::MQTTAsync_getPendingTokens can be called to return the ids of the messages + * waiting to be sent, or for which the sending process has not completed. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTAsync_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page publish Publication example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed\n"); + finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + finished = 1; +} + +void onSendFailure(void* context, MQTTAsync_failureData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message send failed token %d error code %d\n", response->token, response->code); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +void onSend(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message with token value %d delivery confirmed\n", response->token); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response ? response->code : 0); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + MQTTAsync_message pubmsg = MQTTAsync_message_initializer; + int rc; + + printf("Successful connection\n"); + opts.onSuccess = onSend; + opts.onFailure = onSendFailure; + opts.context = client; + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start sendMessage, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +int messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* m) +{ + // not expecting any messages + return 1; +} + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to create client object, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + if ((rc = MQTTAsync_setCallbacks(client, NULL, connlost, messageArrived, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callback, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (!finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + MQTTAsync_destroy(&client); + return rc; +} + + * @endcode + * @page subscribe Subscription example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int disc_finished = 0; +int subscribed = 0; +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + if (cause) + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTAsync_freeMessage(&message); + MQTTAsync_free(topicName); + return 1; +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed, rc %d\n", response->code); + disc_finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + disc_finished = 1; +} + +void onSubscribe(void* context, MQTTAsync_successData* response) +{ + printf("Subscribe succeeded\n"); + subscribed = 1; +} + +void onSubscribeFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Subscribe failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + int rc; + + printf("Successful connection\n"); + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + opts.onSuccess = onSubscribe; + opts.onFailure = onSubscribeFailure; + opts.context = client; + if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start subscribe, return code %d\n", rc); + finished = 1; + } +} + + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer; + int rc; + int ch; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) + != MQTTASYNC_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTAsync_setCallbacks(client, client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + while (!subscribed && !finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + if (finished) + goto exit; + + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + disc_opts.onSuccess = onDisconnect; + disc_opts.onFailure = onDisconnectFailure; + if ((rc = MQTTAsync_disconnect(client, &disc_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + while (!disc_finished) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + +destroy_exit: + MQTTAsync_destroy(&client); +exit: + return rc; +} + + * @endcode +* @page tracing Tracing + * + * Runtime tracing can be controlled by environment variables or API calls. + * + * #### Environment variables + * + * Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable. + * A value of ON, or stdout, prints to stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * #### Trace API calls + * + * MQTTAsync_traceCallback() is used to set a callback function which is called whenever trace + * information is available. This will be the same information as that printed if the + * environment variables were used to control the trace. + * + * The MQTTAsync_setTraceLevel() calls is used to set the maximum level of trace entries that will be + * passed to the callback function. The levels are: + * 1. ::MQTTASYNC_TRACE_MAXIMUM + * 2. ::MQTTASYNC_TRACE_MEDIUM + * 3. ::MQTTASYNC_TRACE_MINIMUM + * 4. ::MQTTASYNC_TRACE_PROTOCOL + * 5. ::MQTTASYNC_TRACE_ERROR + * 6. ::MQTTASYNC_TRACE_SEVERE + * 7. ::MQTTASYNC_TRACE_FATAL + * + * Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned. + * Choosing ::MQTTASYNC_TRACE_ERROR will cause ERROR, SEVERE and FATAL trace entries to be returned + * to the callback function. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ + +#if defined(__cplusplus) + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTAsyncUtils.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTAsyncUtils.h new file mode 100644 index 0000000..42a3145 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTAsyncUtils.h @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + +#if !defined(MQTTASYNCUTILS_H_) +#define MQTTASYNCUTILS_H_ + +#include "MQTTPacket.h" +#include "Thread.h" + +#define URI_TCP "tcp://" +#define URI_WS "ws://" +#define URI_WSS "wss://" + +enum MQTTAsync_threadStates +{ + STOPPED, STARTING, RUNNING, STOPPING +}; + +typedef struct +{ + MQTTAsync_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} qEntry; + +typedef struct +{ + int type; + MQTTAsync_onSuccess* onSuccess; + MQTTAsync_onFailure* onFailure; + MQTTAsync_onSuccess5* onSuccess5; + MQTTAsync_onFailure5* onFailure5; + MQTTAsync_token token; + void* context; + START_TIME_TYPE start_time; + MQTTProperties properties; + union + { + struct + { + int count; + char** topics; + int* qoss; + MQTTSubscribe_options opts; + MQTTSubscribe_options* optlist; + } sub; + struct + { + int count; + char** topics; + } unsub; + struct + { + char* destinationName; + int payloadlen; + void* payload; + int qos; + int retained; + } pub; + struct + { + int internal; + int timeout; + enum MQTTReasonCodes reasonCode; + } dis; + struct + { + int currentURI; + int MQTTVersion; /**< current MQTT version being used to connect */ + } conn; + } details; +} MQTTAsync_command; + +typedef struct MQTTAsync_struct +{ + char* serverURI; + int ssl; + int websocket; + Clients* c; + + /* "Global", to the client, callback definitions */ + MQTTAsync_connectionLost* cl; + MQTTAsync_messageArrived* ma; + MQTTAsync_deliveryComplete* dc; + void* clContext; /* the context to be associated with the conn lost callback*/ + void* maContext; /* the context to be associated with the msg arrived callback*/ + void* dcContext; /* the context to be associated with the deliv complete callback*/ + + MQTTAsync_connected* connected; + void* connected_context; /* the context to be associated with the connected callback*/ + + MQTTAsync_disconnected* disconnected; + void* disconnected_context; /* the context to be associated with the disconnected callback*/ + + MQTTAsync_updateConnectOptions* updateConnectOptions; + void* updateConnectOptions_context; + + /* Each time connect is called, we store the options that were used. These are reused in + any call to reconnect, or an automatic reconnect attempt */ + MQTTAsync_command connect; /* Connect operation properties */ + MQTTAsync_command disconnect; /* Disconnect operation properties */ + MQTTAsync_command* pending_write; /* Is there a socket write pending? */ + + List* responses; + unsigned int command_seqno; + + MQTTPacket* pack; + + /* added for offline buffering */ + MQTTAsync_createOptions* createOptions; + int shouldBeConnected; + int noBufferedMessages; /* the current number of buffered (publish) messages for this client */ + + /* added for automatic reconnect */ + int automaticReconnect; + int minRetryInterval; + int maxRetryInterval; + int serverURIcount; + char** serverURIs; + int connectTimeout; + + int currentInterval; + int currentIntervalBase; + START_TIME_TYPE lastConnectionFailedTime; + int retrying; + int reconnectNow; + + /* MQTT V5 properties */ + MQTTProperties* connectProps; + MQTTProperties* willProps; + +} MQTTAsyncs; + +typedef struct +{ + MQTTAsync_command command; + MQTTAsyncs* client; + unsigned int seqno; /* only used on restore */ + int not_restored; + char* key; /* if not_restored, this holds the key */ +} MQTTAsync_queuedCommand; + +void MQTTAsync_lock_mutex(mutex_type amutex); +void MQTTAsync_unlock_mutex(mutex_type amutex); +void MQTTAsync_terminate(void); +#if !defined(NO_PERSISTENCE) +int MQTTAsync_restoreCommands(MQTTAsyncs* client); +#endif +int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size); +void MQTTAsync_emptyMessageQueue(Clients* client); +void MQTTAsync_freeResponses(MQTTAsyncs* m); +void MQTTAsync_freeCommands(MQTTAsyncs* m); +int MQTTAsync_unpersistCommandsAndMessages(Clients* c); +void MQTTAsync_closeSession(Clients* client, enum MQTTReasonCodes reasonCode, MQTTProperties* props); +int MQTTAsync_disconnect1(MQTTAsync handle, const MQTTAsync_disconnectOptions* options, int internal); +int MQTTAsync_assignMsgId(MQTTAsyncs* m); +int MQTTAsync_getNoBufferedMessages(MQTTAsyncs* m); +void MQTTAsync_writeComplete(int socket, int rc); +void setRetryLoopInterval(int keepalive); + +#if defined(_WIN32) || defined(_WIN64) +#else +#define WINAPI +#endif + +thread_return_type WINAPI MQTTAsync_sendThread(void* n); +thread_return_type WINAPI MQTTAsync_receiveThread(void* n); + +#endif /* MQTTASYNCUTILS_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTClient.h new file mode 100644 index 0000000..da61357 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTClient.h @@ -0,0 +1,1945 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - remove const from eyecatchers #168 + *******************************************************************************/ + +/** + * @cond MQTTClient_internal + * @mainpage MQTT Client Library Internals + * In the beginning there was one MQTT C client library, MQTTClient, as implemented in MQTTClient.c + * This library was designed to be easy to use for applications which didn't mind if some of the calls + * blocked for a while. For instance, the MQTTClient_connect call will block until a successful + * connection has completed, or a connection has failed, which could be as long as the "connection + * timeout" interval, whose default is 30 seconds. + * + * However in mobile devices and other windowing environments, blocking on the GUI thread is a bad + * thing as it causes the user interface to freeze. Hence a new API, MQTTAsync, implemented + * in MQTTAsync.c, was devised. There are no blocking calls in this library, so it is well suited + * to GUI and mobile environments, at the expense of some extra complexity. + * + * Both libraries are designed to be sparing in the use of threads. So multiple client objects are + * handled by one or two threads, with a select call in Socket_getReadySocket(), used to determine + * when a socket has incoming data. This API is thread safe: functions may be called by multiple application + * threads, with the exception of ::MQTTClient_yield and ::MQTTClient_receive, which are intended + * for single threaded environments only. + * + * @endcond + * @cond MQTTClient_main + * @mainpage MQTT Client library for C + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An MQTT client library in C. + * + * These pages describe the original more synchronous API which might be + * considered easier to use. Some of the calls will block. For the new + * totally asynchronous API where no calls block, which is especially suitable + * for use in windowed environments, see the + * MQTT C Client Asynchronous API Documentation. + * The MQTTClient API is not thread safe, whereas the MQTTAsync API is. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions if multi-threaded (asynchronous mode) + * operation is being used (see @ref async).
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref pubsync
  • + *
  • @ref pubasync
  • + *
  • @ref subasync
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref callbacks
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENT_H) +#define MQTTCLIENT_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTCLIENT_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTCLIENT_FAILURE -1 + +/* error code -2 is MQTTCLIENT_PERSISTENCE_ERROR */ + +/** + * Return code: The client is disconnected. + */ +#define MQTTCLIENT_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTCLIENT_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTCLIENT_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTCLIENT_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTCLIENT_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTCLIENT_BAD_STRUCTURE -8 +/** + * Return code: A QoS value that falls outside of the acceptable range (0,1,2) + */ +#define MQTTCLIENT_BAD_QOS -9 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTCLIENT_SSL_NOT_SUPPORTED -10 + /** + * Return code: unrecognized MQTT version + */ + #define MQTTCLIENT_BAD_MQTT_VERSION -11 +/** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + */ +#define MQTTCLIENT_BAD_PROTOCOL -14 + /** + * Return code: option not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic on connect + */ + #define MQTTCLIENT_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 + /** + * MQTT version to connect with: 5 + */ + #define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTClient_init_options; + +#define MQTTClient_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library (0) + */ +LIBMQTT_API void MQTTClient_global_init(MQTTClient_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTClient_create(). + */ +typedef void* MQTTClient; +/** + * A value representing an MQTT message. A delivery token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTClient_publish(), + * MQTTClient_publishMessage(), + * MQTTClient_deliveryComplete(), + * MQTTClient_waitForCompletion() and + * MQTTClient_getPendingDeliveryTokens()). + */ +typedef int MQTTClient_deliveryToken; +typedef int MQTTClient_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTClient_publishMessage(), + * MQTTClient_publish(), MQTTClient_receive(), MQTTClient_freeMessage() + * and MQTTClient_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. + */ + int dup; + /** The message identifier is normally reserved for internal use by the + * MQTT client and server. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTClient_message; + +#define MQTTClient_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTClient_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTClient_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTClient_freeMessage must be called. + * To free the topic name storage, ::MQTTClient_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTClient_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTClient_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages. The function is registered with the + * client library by passing it as an argument to MQTTClient_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note:MQTTClient_deliveryComplete() is not called when messages are + * published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken dt); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTClient_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_connectionLost(void* context, char* cause); + +/** + * This function sets the callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Calling MQTTClient_setCallbacks() puts the + * client into multi-threaded mode. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. See @ref async for more information. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTClient_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTClient_messageArrived() callback + * function. This callback function must be set when you call + * MQTTClient_setCallbacks(), as otherwise there would be nowhere to deliver + * any incoming messages. + * @param dc A pointer to an MQTTClient_deliveryComplete() callback + * function. You can set this to NULL if your application publishes + * synchronously or if you do not want to check for successful delivery. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl, + MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc); + + +/** + * This is a callback function, which will be called when the a disconnect + * packet is received from the server. This applies to MQTT V5 and above only. + * @param context A pointer to the context value originally passed to + * ::MQTTClient_setDisconnected(), which contains any application-specific context. + * @param properties The MQTT V5 properties received with the disconnect, if any. + * @param reasonCode The MQTT V5 reason code received with the disconnect. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTClient_disconnected() callback function for a client. This will be called + * if a disconnect packet is received from the server. Only valid for MQTT V5 and above. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTClient_disconnected() callback + * function. NULL removes the callback setting. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setDisconnected(MQTTClient handle, void* context, MQTTClient_disconnected* co); + +/** + * This is a callback function, the MQTT V5 version of MQTTClient_deliveryComplete(). + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the completed delivery of messages. + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note: It is not called when messages are published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + * @param packet_type the last received packet type for this completion. For QoS 1 + * always PUBACK. For QoS 2 could be PUBREC or PUBCOMP. + * @param properties the MQTT V5 properties returned with the last packet from the server + * @param reasonCode the reason code returned from the server + */ +typedef void MQTTClient_published(void* context, int dt, int packet_type, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +LIBMQTT_API int MQTTClient_setPublished(MQTTClient handle, void* context, MQTTClient_published* co); + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTClient_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; +} MQTTClient_createOptions; + +#define MQTTClient_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, MQTTVERSION_DEFAULT } + +/** + * A version of :MQTTClient_create() with additional options. + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp or ssl. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @param options additional options for the create. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_createWithOptions(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTClient_createOptions* options); + +/** + * MQTTClient_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTClient_willOptions + * structure is passed in the MQTTClient_connectOptions structure used in the + * MQTTClient_connect() call that connects the client to the server. The pointer + * to MQTTClient_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 means there is no binary payload option + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload in string form. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTClient_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTClient_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTClient_willOptions; + +#define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTClient_SSLOptions; + +#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** + * MQTTClient_libraryInfo is used to store details relating to the currently used + * library such as the version in use, the time it was built and relevant openSSL + * options. + * There is one static instance of this struct in MQTTClient.c + */ + +typedef struct +{ + const char* name; + const char* value; +} MQTTClient_nameValue; + +/** + * This function returns version information about the library. + * no trace information will be returned. + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTClient_nameValue* MQTTClient_getVersionInfo(void); + +/** + * MQTTClient_connectOptions defines several settings that control the way the + * client connects to an MQTT server. + * + * Note: Default values are not defined for members of + * MQTTClient_connectOptions so it is good practice to specify all settings. + * If the MQTTClient_connectOptions structure is defined as an automatic + * variable, all members are set to random values and thus must be set by the + * client application. If the MQTTClient_connectOptions structure is defined + * as a static variable, initialization (in compliant compilers) sets all + * values to 0 (NULL for pointers). A #keepAliveInterval setting of 0 prevents + * correct operation of the client and so you must at least set a value + * for #keepAliveInterval. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3, 4, 5, 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no returned values + * 4 signifies no binary password option + * 5 signifies no maxInflightMessages and cleanstart + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTClient_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This is a boolean value that controls how many messages can be in-flight + * simultaneously. Setting reliable to true means that a published + * message must be completed (acknowledgements received) before another + * can be sent. Attempts to publish additional messages receive an + * ::MQTTCLIENT_MAX_MESSAGES_INFLIGHT return code. Setting this flag to + * false allows up to 10 messages to be in-flight. This can increase + * overall throughput in some circumstances. + */ + int reliable; + /** + * This is a pointer to an MQTTClient_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTClient_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTClient_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTClient_SSLOptions* ssl; + /** + * The number of entries in the optional serverURIs array. Defaults to 0. + */ + int serverURIcount; + /** + * An optional array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * If this list is empty (the default), the server URI specified on MQTTClient_create() + * is used. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + * MQTTVERSION_5 (5) = only try version 5.0 + */ + int MQTTVersion; + /** + * Returned from the connect when the MQTT version used to connect is 3.1.1 + */ + struct + { + const char* serverURI; /**< the serverURI connected to */ + int MQTTVersion; /**< the MQTT version used to connect with */ + int sessionPresent; /**< if the MQTT version is 3.1.1, the value of sessionPresent returned in the connack */ + } returned; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct + { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /** + * The maximum number of messages in flight + */ + int maxInflightMessages; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * HTTP headers for websockets + */ + const MQTTClient_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTClient_connectOptions; + +#define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +/** + * This function attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @return ::MQTTCLIENT_SUCCESS if the client successfully connects to the + * server. An error code is returned if the client was unable to connect to + * the server. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options); + +/** MQTT version 5.0 response information */ +typedef struct MQTTResponse +{ + int version; /* the version number of this structure */ + enum MQTTReasonCodes reasonCode; /* the MQTT 5.0 reason code returned */ + int reasonCodeCount; /* the number of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + enum MQTTReasonCodes* reasonCodes; /* a list of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + MQTTProperties* properties; /* optionally, the MQTT 5.0 properties returned */ +} MQTTResponse; + +#define MQTTResponse_initializer {1, MQTTREASONCODE_SUCCESS, 0, NULL, NULL} + +/** + * Frees the storage associated with the MQTT response. + * @param response the response structure to be freed + */ +LIBMQTT_API void MQTTResponse_free(MQTTResponse response); + +/** + * Attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using MQTT version 5.0 and the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @param connectProperties the MQTT 5.0 connect properties to use + * @param willProperties the MQTT 5.0 properties to set on the will message + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_connect5(MQTTClient handle, MQTTClient_connectOptions* options, + MQTTProperties* connectProperties, MQTTProperties* willProperties); + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTClient_connectOptions.cleansession and MQTTClient_connect()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param timeout The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTClient_disconnect(MQTTClient handle, int timeout); + +LIBMQTT_API int MQTTClient_disconnect5(MQTTClient handle, int timeout, enum MQTTReasonCodes reason, MQTTProperties* props); + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTClient_isConnected(MQTTClient handle); + + +/* Subscribe is synchronous. QoS list parameter is changed on return to granted QoSs. + Returns return code, MQTTCLIENT_SUCCESS == success, non-zero some sort of error (TBD) */ + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTClient_subscribe(MQTTClient handle, const char* topic, int qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribe5(MQTTClient handle, const char* topic, int qos, + MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribeMany5(MQTTClient handle, int count, char* const* topic, + int* qos, MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @return ::MQTTCLIENT_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTClient_unsubscribe(MQTTClient handle, const char* topic); + +/** + * This function attempts to remove an existing subscription made by the + * specified client using MQTT 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribe5(MQTTClient handle, const char* topic, MQTTProperties* props); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @return ::MQTTCLIENT_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client using MQTT version 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribeMany5(MQTTClient handle, int count, char* const* topic, MQTTProperties* props); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publishMessage()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publish(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, int qos, int retained, + MQTTClient_deliveryToken* dt); + +/** + * Attempts to publish a message to a given topic using MQTT version 5.0 (see also + * MQTTClient_publishMessage5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param properties the MQTT 5.0 properties to be used + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publish5(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, + int qos, int retained, MQTTProperties* properties, MQTTClient_deliveryToken* dt); +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publishMessage(MQTTClient handle, const char* topicName, MQTTClient_message* msg, MQTTClient_deliveryToken* dt); + + +/** + * Attempts to publish a message to the given topic using MQTT version 5.0 + * (see also + * MQTTClient_publish5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char* topicName, MQTTClient_message* msg, + MQTTClient_deliveryToken* dt); + +/** + * This function is called by the client application to synchronize execution + * of the main thread with completed publication of a message. When called, + * MQTTClient_waitForCompletion() blocks execution until the message has been + * successful delivered or the specified timeout has expired. See @ref async. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param dt The ::MQTTClient_deliveryToken that represents the message being + * tested for successful delivery. Delivery tokens are issued by the + * publishing functions MQTTClient_publish() and MQTTClient_publishMessage(). + * @param timeout The maximum time to wait in milliseconds. + * @return ::MQTTCLIENT_SUCCESS if the message was successfully delivered. + * An error code is returned if the timeout expires or there was a problem + * checking the token. + */ +LIBMQTT_API int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken dt, unsigned long timeout); + + +/** + * This function sets a pointer to an array of delivery tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param tokens The address of a pointer to an ::MQTTClient_deliveryToken. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTCLIENT_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTClient_getPendingDeliveryTokens(MQTTClient handle, MQTTClient_deliveryToken **tokens); + +/** + * When implementing a single-threaded client, call this function periodically + * to allow processing of message retries and to send MQTT keepalive pings. + * If the application is calling MQTTClient_receive() regularly, then it is + * not necessary to call this function. + */ +LIBMQTT_API void MQTTClient_yield(void); + +/** + * This function performs a synchronous receive of incoming messages. It should + * be used only when the client application has not set callback methods to + * support asynchronous receipt of messages (see @ref async and + * MQTTClient_setCallbacks()). Using this function allows a single-threaded + * client subscriber application to be written. When called, this function + * blocks until the next message arrives or the specified timeout expires + *(see also MQTTClient_yield()). + * + * Important note: The application must free() the memory allocated + * to the topic and the message when processing is complete (see + * MQTTClient_freeMessage()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The address of a pointer to a topic. This function + * allocates the memory for the topic and returns it to the application + * by setting topicName to point to the topic. + * @param topicLen The length of the topic. If the return code from this + * function is ::MQTTCLIENT_TOPICNAME_TRUNCATED, the topic contains embedded + * NULL characters and the full topic should be retrieved by using + * topicLen. + * @param message The address of a pointer to the received message. This + * function allocates the memory for the message and returns it to the + * application by setting message to point to the received message. + * The pointer is set to NULL if the timeout expires. + * @param timeout The length of time to wait for a message in milliseconds. + * @return ::MQTTCLIENT_SUCCESS or ::MQTTCLIENT_TOPICNAME_TRUNCATED if a + * message is received. ::MQTTCLIENT_SUCCESS can also indicate that the + * timeout expired, in which case message is NULL. An error code is + * returned if there was a problem trying to receive a message. + */ +LIBMQTT_API int MQTTClient_receive(MQTTClient handle, char** topicName, int* topicLen, MQTTClient_message** message, + unsigned long timeout); + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTClient_free() library function. + * @param msg The address of a pointer to the ::MQTTClient_message structure + * to be freed. + */ +LIBMQTT_API void MQTTClient_freeMessage(MQTTClient_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client libary and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTClient_free(void* ptr); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTClient_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTClient + * structure to be freed. + */ +LIBMQTT_API void MQTTClient_destroy(MQTTClient* handle); + + +enum MQTTCLIENT_TRACE_LEVELS +{ + MQTTCLIENT_TRACE_MAXIMUM = 1, + MQTTCLIENT_TRACE_MEDIUM, + MQTTCLIENT_TRACE_MINIMUM, + MQTTCLIENT_TRACE_PROTOCOL, + MQTTCLIENT_TRACE_ERROR, + MQTTCLIENT_TRACE_SEVERE, + MQTTCLIENT_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTClient_setTraceLevel(enum MQTTCLIENT_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTClient_traceCallback(enum MQTTCLIENT_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTClient_setTraceCallback(MQTTClient_traceCallback* callback); + +/** + * Sets the timeout value for un/subscribe commands when waiting for the un/suback response from + * the server. Values less than 5000 are not allowed. + * @param handle A valid client handle from a successful call to MQTTClient_create(). + * @param milliSeconds the maximum number of milliseconds to wait + * @return MQTTCLIENT_SUCCESS or MQTTCLIENT_FAILURE + */ +LIBMQTT_API int MQTTClient_setCommandTimeout(MQTTClient handle, unsigned long milliSeconds); + +/** + * Returns a pointer to the string representation of the error or NULL. + * + * Do not free after use. Returns NULL if the error code is unknown. + */ +LIBMQTT_API const char* MQTTClient_strerror(int code); + +#if defined(__cplusplus) + } +#endif + +#endif + +/*! + * @cond MQTTClient_main + * @page async Asynchronous vs synchronous client applications + * This client library supports two modes of operation. These are referred to + * as synchronous and asynchronous modes. If your application + * calls MQTTClient_setCallbacks(), this puts the client into asynchronous + * mode, otherwise it operates in synchronous mode. + * + * In synchronous mode, the client application runs on a single thread. + * Messages are published using the MQTTClient_publish() and + * MQTTClient_publishMessage() functions. To determine that a QoS1 or QoS2 + * (see @ref qos) message has been successfully delivered, the application + * must call the MQTTClient_waitForCompletion() function. An example showing + * synchronous publication is shown in @ref pubsync. Receiving messages in + * synchronous mode uses the MQTTClient_receive() function. Client applications + * must call either MQTTClient_receive() or MQTTClient_yield() relatively + * frequently in order to allow processing of acknowledgements and the MQTT + * "pings" that keep the network connection to the server alive. + * + * In asynchronous mode, the client application runs on several threads. The + * main program calls functions in the client library to publish and subscribe, + * just as for the synchronous mode. Processing of handshaking and maintaining + * the network connection is performed in the background, however. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTClient_setCallbacks() (see MQTTClient_messageArrived(), + * MQTTClient_connectionLost() and MQTTClient_deliveryComplete()). + * This API is not thread safe however - it is not possible to call it from multiple + * threads without synchronization. You can use the MQTTAsync API for that. + * + * @page callbacks Callbacks + * You must not call a function from this API from within a callback otherwise + * a deadlock might result. The only exception to this is the ability to call + * connect within the connection lost callback, to allow a reconnect. + * + * When using MQTT 5.0, you can also call connect from within the disconnected + * callback, which is invoked when the MQTT server sends a disconnect packet. + * This server behaviour is allowed in MQTT 5.0, but not in MQTT 3.1.1, so the + * disconnected callback will never be invoked if you use MQTT 3.1.1. + * + * In particular, you must make a publish call within the message arrived callback. + * These restrictions are all lifted in the + * MQTTAsync API. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, or receive not called, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * It is up to the application to protect against this situation. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTClient_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTClient_subscribe() and MQTTClient_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page pubsync Synchronous publication example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for up to %d seconds for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID); + rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); + printf("Message with delivery token %d delivered\n", token); + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + printf("Failed to disconnect, return code %d\n", rc); + MQTTClient_destroy(&client); + return rc; +} + + * @endcode + * + * @page pubasync Asynchronous publication example +@code{.c} +#include +#include +#include +#include "MQTTClient.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + deliveredtoken = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (deliveredtoken != token) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } + +destroy_exit: + MQTTClient_destroy(&client); + +exit: + return rc; +} + + * @endcode + * @page subasync Asynchronous subscription example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +volatile MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + if ((rc = MQTTClient_subscribe(client, TOPIC, QOS)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to subscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + int ch; + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + if ((rc = MQTTClient_unsubscribe(client, TOPIC)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to unsubscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } +destroy_exit: + MQTTClient_destroy(&client); +exit: + return rc; +} + + * @endcode + * @page tracing Tracing + * + * Runtime tracing is controlled by environment variables. + * + * Tracing is switched on by setting MQTT_C_CLIENT_TRACE. A value of ON, or stdout, prints to + * stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTClientPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTClientPersistence.h new file mode 100644 index 0000000..d3caae4 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTClientPersistence.h @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** + * @file + * \brief This structure represents a persistent data store, used to store + * outbound and inbound messages, in order to achieve reliable messaging. + * + * The MQTT Client persists QoS1 and QoS2 messages in order to meet the + * assurances of delivery associated with these @ref qos levels. The messages + * are saved in persistent storage + * The type and context of the persistence implementation are specified when + * the MQTT client is created (see MQTTClient_create()). The default + * persistence type (::MQTTCLIENT_PERSISTENCE_DEFAULT) uses a file system-based + * persistence mechanism. The persistence_context argument passed to + * MQTTClient_create() when using the default peristence is a string + * representing the location of the persistence directory. If the context + * argument is NULL, the working directory will be used. + * + * To use memory-based persistence, an application passes + * ::MQTTCLIENT_PERSISTENCE_NONE as the persistence_type to + * MQTTClient_create(). This can lead to message loss in certain situations, + * but can be appropriate in some cases (see @ref qos). + * + * Client applications can provide their own persistence mechanism by passing + * ::MQTTCLIENT_PERSISTENCE_USER as the persistence_type. To implement a + * custom persistence mechanism, the application must pass an initialized + * ::MQTTClient_persistence structure as the persistence_context + * argument to MQTTClient_create(). + * + * If the functions defined return an ::MQTTCLIENT_PERSISTENCE_ERROR then the + * state of the persisted data should remain as it was prior to the function + * being called. For example, if Persistence_put() returns + * ::MQTTCLIENT_PERSISTENCE_ERROR, then it is assumed tha tthe persistent store + * does not contain the data that was passed to the function. Similarly, if + * Persistence_remove() returns ::MQTTCLIENT_PERSISTENCE_ERROR then it is + * assumed that the data to be removed is still held in the persistent store. + * + * It is up to the persistence implementation to log any error information that + * may be required to diagnose a persistence mechanism failure. + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENTPERSISTENCE_H) +#define MQTTCLIENTPERSISTENCE_H +/* +/// @endcond +*/ + +/** + * This persistence_type value specifies the default file system-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_DEFAULT 0 +/** + * This persistence_type value specifies a memory-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_NONE 1 +/** + * This persistence_type value specifies an application-specific + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_USER 2 + +/** + * Application-specific persistence functions must return this error code if + * there is a problem executing the function. + */ +#define MQTTCLIENT_PERSISTENCE_ERROR -2 + +/** + * @brief Initialize the persistent store. + * + * Either open the existing persistent store for this client ID or create a new + * one if one doesn't exist. If the persistent store is already open, return + * without taking any action. + * + * An application can use the same client identifier to connect to many + * different servers. The clientid in conjunction with the + * serverURI uniquely identifies the persistence store required. + * + * @param handle The address of a pointer to a handle for this persistence + * implementation. This function must set handle to a valid reference to the + * persistence following a successful return. + * The handle pointer is passed as an argument to all the other + * persistence functions. It may include the context parameter and/or any other + * data for use by the persistence functions. + * @param clientID The client identifier for which the persistent store should + * be opened. + * @param serverURI The connection string specified when the MQTT client was + * created (see MQTTClient_create()). + * @param context A pointer to any data required to initialize the persistent + * store (see ::MQTTClient_persistence). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_open)(void** handle, const char* clientID, const char* serverURI, void* context); + +/** + * @brief Close the persistent store referred to by the handle. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_close)(void* handle); + +/** + * @brief Put the specified data into the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string used as the key for the data to be put in the store. The + * key is later used to retrieve data from the store with Persistence_get(). + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers associated with + * this key. + * @param buflens An array of lengths of the data buffers. buflen[n] + * gives the length of buffer[n]. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_put)(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); + +/** + * @brief Retrieve the specified data from the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be retrieved. This is + * the same key used to save the data to the store with Persistence_put(). + * @param buffer The address of a pointer to a buffer. This function sets the + * pointer to point at the retrieved data, if successful. + * @param buflen The address of an int that is set to the length of + * buffer by this function if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_get)(void* handle, char* key, char** buffer, int* buflen); + +/** + * @brief Remove the data for the specified key from the store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be removed from the + * store. This is the same key used to save the data to the store with + * Persistence_put(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_remove)(void* handle, char* key); + +/** + * @brief Returns the keys in this persistent data store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param keys The address of a pointer to pointers to strings. Assuming + * successful execution, this function allocates memory to hold the returned + * keys (strings used to store the data with Persistence_put()). It also + * allocates memory to hold an array of pointers to these strings. keys + * is set to point to the array of pointers to strings. + * @param nkeys A pointer to the number of keys in this persistent data store. + * This function sets the number of keys, if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_keys)(void* handle, char*** keys, int* nkeys); + +/** + * @brief Clears the persistence store, so that it no longer contains any + * persisted data. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_clear)(void* handle); + +/** + * @brief Returns whether any data has been persisted using the specified key. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key The string to be tested for existence in the store. + * @return Return 0 if the key was found in the store, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_containskey)(void* handle, char* key); + +/** + * @brief A structure containing the function pointers to a persistence + * implementation and the context or state that will be shared across all + * the persistence functions. + */ +typedef struct { + /** + * A pointer to any data required to initialize the persistent store. + */ + void* context; + /** + * A function pointer to an implementation of Persistence_open(). + */ + Persistence_open popen; + /** + * A function pointer to an implementation of Persistence_close(). + */ + Persistence_close pclose; + /** + * A function pointer to an implementation of Persistence_put(). + */ + Persistence_put pput; + /** + * A function pointer to an implementation of Persistence_get(). + */ + Persistence_get pget; + /** + * A function pointer to an implementation of Persistence_remove(). + */ + Persistence_remove premove; + /** + * A function pointer to an implementation of Persistence_keys(). + */ + Persistence_keys pkeys; + /** + * A function pointer to an implementation of Persistence_clear(). + */ + Persistence_clear pclear; + /** + * A function pointer to an implementation of Persistence_containskey(). + */ + Persistence_containskey pcontainskey; +} MQTTClient_persistence; + + +/** + * A callback which is invoked just before a write to persistence. This can be + * used to transform the data, for instance to encrypt it. + * @param context The context as set in ::MQTTAsync_setBeforePersistenceWrite + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers. + * @param buflens An array of lengths of the data buffers. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_beforeWrite(void* context, int bufcount, char* buffers[], int buflens[]); + + +/** + * A callback which is invoked just after a read from persistence. This can be + * used to transform the data, for instance to decrypt it. + * @param context The context as set in ::MQTTAsync_setAfterPersistenceRead + * @param buffer The address of a pointer to a buffer. + * @param buflen The address of an int that is the length of the buffer. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_afterRead(void* context, char** buffer, int* buflen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTExportDeclarations.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTExportDeclarations.h new file mode 100644 index 0000000..d492ef1 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTExportDeclarations.h @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 Andreas Walter + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Andreas Walter - initially moved export declarations into separate fle + *******************************************************************************/ + +#if !defined(EXPORTDECLARATIONS_H) +#define EXPORTDECLARATIONS_H + +#if defined(_WIN32) || defined(_WIN64) +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __declspec(dllexport) +# elif defined(PAHO_MQTT_IMPORTS) +# define LIBMQTT_API __declspec(dllimport) +# else +# define LIBMQTT_API +# endif +#else +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __attribute__ ((visibility ("default"))) +# else +# define LIBMQTT_API extern +# endif +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPacket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPacket.h new file mode 100644 index 0000000..658404a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPacket.h @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - big endian Linux reversed definition + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKET_H) +#define MQTTPACKET_H + +#include "Socket.h" +#if defined(OPENSSL) +#include "SSLSocket.h" +#endif +#include "LinkedList.h" +#include "Clients.h" + +typedef unsigned int bool; +typedef void* (*pf)(int, unsigned char, char*, size_t); + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" + +enum errors +{ + MQTTPACKET_BAD = -4, + MQTTPACKET_BUFFER_TOO_SHORT = -2, + MQTTPACKET_READ_ERROR = -1, + MQTTPACKET_READ_COMPLETE +}; + + +enum msgTypes +{ + CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, + PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, + PINGREQ, PINGRESP, DISCONNECT, AUTH +}; + +#if defined(__linux__) +#include +#if __BYTE_ORDER == __BIG_ENDIAN + #define REVERSED 1 +#endif +#endif + +/** + * Bitfields for the MQTT header byte. + */ +typedef union +{ + /*unsigned*/ char byte; /**< the whole byte */ +#if defined(REVERSED) + struct + { + unsigned int type : 4; /**< message type nibble */ + bool dup : 1; /**< DUP flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool retain : 1; /**< retained flag bit */ + } bits; +#else + struct + { + bool retain : 1; /**< retained flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool dup : 1; /**< DUP flag bit */ + unsigned int type : 4; /**< message type nibble */ + } bits; +#endif +} Header; + + +/** + * Data for a connect packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connect flags */ +#if defined(REVERSED) + struct + { + bool username : 1; /**< 3.1 user name */ + bool password : 1; /**< 3.1 password */ + bool willRetain : 1; /**< will retain setting */ + unsigned int willQoS : 2; /**< will QoS value */ + bool will : 1; /**< will flag */ + bool cleanstart : 1; /**< cleansession flag */ + int : 1; /**< unused */ + } bits; +#else + struct + { + int : 1; /**< unused */ + bool cleanstart : 1; /**< cleansession flag */ + bool will : 1; /**< will flag */ + unsigned int willQoS : 2; /**< will QoS value */ + bool willRetain : 1; /**< will retain setting */ + bool password : 1; /**< 3.1 password */ + bool username : 1; /**< 3.1 user name */ + } bits; +#endif + } flags; /**< connect flags byte */ + + char *Protocol, /**< MQTT protocol name */ + *clientID, /**< string client id */ + *willTopic, /**< will topic */ + *willMsg; /**< will payload */ + + int keepAliveTimer; /**< keepalive timeout value in seconds */ + unsigned char version; /**< MQTT version number */ +} Connect; + + +/** + * Data for a connack packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connack flags */ +#if defined(REVERSED) + struct + { + unsigned int reserved : 7; /**< message type nibble */ + bool sessionPresent : 1; /**< was a session found on the server? */ + } bits; +#else + struct + { + bool sessionPresent : 1; /**< was a session found on the server? */ + unsigned int reserved : 7; /**< message type nibble */ + } bits; +#endif + } flags; /**< connack flags byte */ + unsigned char rc; /**< connack reason code */ + unsigned int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Connack; + + +/** + * Data for a packet with header only. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ +} MQTTPacket; + + +/** + * Data for a suback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* qoss; /**< list of granted QoSs (MQTT 3/4) / reason codes (MQTT 5) */ +} Suback; + + +/** + * Data for an MQTT V5 unsuback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* reasonCodes; /**< list of reason codes */ +} Unsuback; + + +/** + * Data for a publish packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + char* topic; /**< topic string */ + int topiclen; + int msgId; /**< MQTT message id */ + char* payload; /**< binary payload, length delimited */ + int payloadlen; /**< payload length */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + uint8_t mask[4]; /**< the websockets mask the payload is masked with, if any */ +} Publish; + + +/** + * Data for one of the ack packets. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + unsigned char rc; /**< MQTT 5 reason code */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Ack; + +typedef Ack Puback; +typedef Ack Pubrec; +typedef Ack Pubrel; +typedef Ack Pubcomp; + +int MQTTPacket_encode(char* buf, size_t length); +int MQTTPacket_decode(networkHandles* net, size_t* value); +int readInt(char** pptr); +char* readUTF(char** pptr, char* enddata); +unsigned char readChar(char** pptr); +void writeChar(char** pptr, char c); +void writeInt(char** pptr, int anInt); +void writeUTF(char** pptr, const char* string); +void writeData(char** pptr, const void* data, int datalen); + +const char* MQTTPacket_name(int ptype); + +void* MQTTPacket_Factory(int MQTTVersion, networkHandles* net, int* error); +int MQTTPacket_send(networkHandles* net, Header header, char* buffer, size_t buflen, int free, int MQTTVersion); +int MQTTPacket_sends(networkHandles* net, Header header, PacketBuffers* buffers, int MQTTVersion); + +void* MQTTPacket_header_only(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +int MQTTPacket_send_disconnect(Clients* client, enum MQTTReasonCodes reason, MQTTProperties* props); + +void* MQTTPacket_publish(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freePublish(Publish* pack); +int MQTTPacket_send_publish(Publish* pack, int dup, int qos, int retained, networkHandles* net, const char* clientID); +int MQTTPacket_send_puback(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +void MQTTPacket_freeAck(Ack* pack); +void MQTTPacket_freeSuback(Suback* pack); +void MQTTPacket_freeUnsuback(Unsuback* pack); +int MQTTPacket_send_pubrec(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubrel(int MQTTVersion, int msgid, int dup, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubcomp(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); + +void MQTTPacket_free_packet(MQTTPacket* pack); + +void writeInt4(char** pptr, int anInt); +int readInt4(char** pptr); +void writeMQTTLenString(char** pptr, MQTTLenString lenstring); +int MQTTLenStringRead(MQTTLenString* lenstring, char** pptr, char* enddata); +int MQTTPacket_VBIlen(int rem_len); +int MQTTPacket_decodeBuf(char* buf, unsigned int* value); + +#include "MQTTPacketOut.h" + +#endif /* MQTTPACKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPacketOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPacketOut.h new file mode 100644 index 0000000..d962554 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPacketOut.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKETOUT_H) +#define MQTTPACKETOUT_H + +#include "MQTTPacket.h" + +int MQTTPacket_send_connect(Clients* client, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +void* MQTTPacket_connack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freeConnack(Connack* pack); + +int MQTTPacket_send_pingreq(networkHandles* net, const char* clientID); + +int MQTTPacket_send_subscribe(List* topics, List* qoss, MQTTSubscribe_options* opts, MQTTProperties* props, + int msgid, int dup, Clients* client); +void* MQTTPacket_suback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +int MQTTPacket_send_unsubscribe(List* topics, MQTTProperties* props, int msgid, int dup, Clients* client); +void* MQTTPacket_unsuback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPersistence.h new file mode 100644 index 0000000..ed2e0ce --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPersistence.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - async client updates + * Ian Craggs - fix for bug 432903 - queue persistence + * Ian Craggs - MQTT V5 updates + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCE_H) +#define MQTTPERSISTENCE_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include "Clients.h" +#include "MQTTProperties.h" + +/** Stem of the key for a sent PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_PUBLISH_SENT "s-" +/** Stem of the key for a sent PUBREL */ +#define PERSISTENCE_PUBREL "sc-" +/** Stem of the key for a received PUBLISH QoS2 */ +#define PERSISTENCE_PUBLISH_RECEIVED "r-" + +/** Stem of the key for a sent MQTT V5 PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_V5_PUBLISH_SENT "s5-" +/** Stem of the key for a sent MQTT V5 PUBREL */ +#define PERSISTENCE_V5_PUBREL "sc5-" +/** Stem of the key for a received MQTT V5 PUBLISH QoS2 */ +#define PERSISTENCE_V5_PUBLISH_RECEIVED "r5-" + +/** Stem of the key for an async client command */ +#define PERSISTENCE_COMMAND_KEY "c-" +/** Stem of the key for an MQTT V5 async client command */ +#define PERSISTENCE_V5_COMMAND_KEY "c5-" +/** Stem of the key for an client incoming message queue */ +#define PERSISTENCE_QUEUE_KEY "q-" +/** Stem of the key for an MQTT V5 incoming message queue */ +#define PERSISTENCE_V5_QUEUE_KEY "q5-" +/** Maximum length of a stem for a persistence key */ +#define PERSISTENCE_MAX_STEM_LENGTH 3 +/** Maximum allowed length of a persistence key */ +#define PERSISTENCE_MAX_KEY_LENGTH 9 +/** Maximum size of an integer sequence number appended to a persistence key */ +#define PERSISTENCE_SEQNO_LIMIT 1000000 /*10^(PERSISTENCE_MAX_KEY_LENGTH - PERSISTENCE_MAX_STEM_LENGTH)*/ + +int MQTTPersistence_create(MQTTClient_persistence** per, int type, void* pcontext); +int MQTTPersistence_initialize(Clients* c, const char* serverURI); +int MQTTPersistence_close(Clients* c); +int MQTTPersistence_clear(Clients* c); +int MQTTPersistence_restorePackets(Clients* c); +void* MQTTPersistence_restorePacket(int MQTTVersion, char* buffer, size_t buflen); +void MQTTPersistence_insertInOrder(List* list, void* content, size_t size); +int MQTTPersistence_putPacket(int socket, char* buf0, size_t buf0len, int count, + char** buffers, size_t* buflens, int htype, int msgId, int scr, int MQTTVersion); +int MQTTPersistence_remove(Clients* c, char* type, int qos, int msgId); +void MQTTPersistence_wrapMsgID(Clients *c); + +typedef struct +{ + char struct_id[4]; + int struct_version; + int payloadlen; + void* payload; + int qos; + int retained; + int dup; + int msgid; + MQTTProperties properties; +} MQTTPersistence_message; + +typedef struct +{ + MQTTPersistence_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} MQTTPersistence_qEntry; + +int MQTTPersistence_unpersistQueueEntry(Clients* client, MQTTPersistence_qEntry* qe); +int MQTTPersistence_persistQueueEntry(Clients* aclient, MQTTPersistence_qEntry* qe); +int MQTTPersistence_restoreMessageQueue(Clients* c); +#ifdef __cplusplus + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPersistenceDefault.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPersistenceDefault.h new file mode 100644 index 0000000..506b4da --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTPersistenceDefault.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCEDEFAULT_H) +#define MQTTPERSISTENCEDEFAULT_H + +/** 8.3 filesystem */ +#define MESSAGE_FILENAME_LENGTH 8 +/** Extension of the filename */ +#define MESSAGE_FILENAME_EXTENSION ".msg" + +/* prototypes of the functions for the default file system persistence */ +int pstopen(void** handle, const char* clientID, const char* serverURI, void* context); +int pstclose(void* handle); +int pstput(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); +int pstget(void* handle, char* key, char** buffer, int* buflen); +int pstremove(void* handle, char* key); +int pstkeys(void* handle, char*** keys, int* nkeys); +int pstclear(void* handle); +int pstcontainskey(void* handle, char* key); + +int pstmkdir(char *pPathname); + +#endif + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProperties.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProperties.h new file mode 100644 index 0000000..81b8e3a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProperties.h @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPROPERTIES_H) +#define MQTTPROPERTIES_H + +#include "MQTTExportDeclarations.h" + +#define MQTT_INVALID_PROPERTY_ID -2 + +/** The one byte MQTT V5 property indicator */ +enum MQTTPropertyCodes { + MQTTPROPERTY_CODE_PAYLOAD_FORMAT_INDICATOR = 1, /**< The value is 1 */ + MQTTPROPERTY_CODE_MESSAGE_EXPIRY_INTERVAL = 2, /**< The value is 2 */ + MQTTPROPERTY_CODE_CONTENT_TYPE = 3, /**< The value is 3 */ + MQTTPROPERTY_CODE_RESPONSE_TOPIC = 8, /**< The value is 8 */ + MQTTPROPERTY_CODE_CORRELATION_DATA = 9, /**< The value is 9 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIER = 11, /**< The value is 11 */ + MQTTPROPERTY_CODE_SESSION_EXPIRY_INTERVAL = 17, /**< The value is 17 */ + MQTTPROPERTY_CODE_ASSIGNED_CLIENT_IDENTIFER = 18,/**< The value is 18 */ + MQTTPROPERTY_CODE_SERVER_KEEP_ALIVE = 19, /**< The value is 19 */ + MQTTPROPERTY_CODE_AUTHENTICATION_METHOD = 21, /**< The value is 21 */ + MQTTPROPERTY_CODE_AUTHENTICATION_DATA = 22, /**< The value is 22 */ + MQTTPROPERTY_CODE_REQUEST_PROBLEM_INFORMATION = 23,/**< The value is 23 */ + MQTTPROPERTY_CODE_WILL_DELAY_INTERVAL = 24, /**< The value is 24 */ + MQTTPROPERTY_CODE_REQUEST_RESPONSE_INFORMATION = 25,/**< The value is 25 */ + MQTTPROPERTY_CODE_RESPONSE_INFORMATION = 26, /**< The value is 26 */ + MQTTPROPERTY_CODE_SERVER_REFERENCE = 28, /**< The value is 28 */ + MQTTPROPERTY_CODE_REASON_STRING = 31, /**< The value is 31 */ + MQTTPROPERTY_CODE_RECEIVE_MAXIMUM = 33, /**< The value is 33*/ + MQTTPROPERTY_CODE_TOPIC_ALIAS_MAXIMUM = 34, /**< The value is 34 */ + MQTTPROPERTY_CODE_TOPIC_ALIAS = 35, /**< The value is 35 */ + MQTTPROPERTY_CODE_MAXIMUM_QOS = 36, /**< The value is 36 */ + MQTTPROPERTY_CODE_RETAIN_AVAILABLE = 37, /**< The value is 37 */ + MQTTPROPERTY_CODE_USER_PROPERTY = 38, /**< The value is 38 */ + MQTTPROPERTY_CODE_MAXIMUM_PACKET_SIZE = 39, /**< The value is 39 */ + MQTTPROPERTY_CODE_WILDCARD_SUBSCRIPTION_AVAILABLE = 40,/**< The value is 40 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIERS_AVAILABLE = 41,/**< The value is 41 */ + MQTTPROPERTY_CODE_SHARED_SUBSCRIPTION_AVAILABLE = 42/**< The value is 241 */ +}; + +/** + * Returns a printable string description of an MQTT V5 property code. + * @param value an MQTT V5 property code. + * @return the printable string description of the input property code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTPropertyName(enum MQTTPropertyCodes value); + +/** The one byte MQTT V5 property type */ +enum MQTTPropertyTypes { + MQTTPROPERTY_TYPE_BYTE, + MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER, + MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER, + MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER, + MQTTPROPERTY_TYPE_BINARY_DATA, + MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING, + MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR +}; + +/** + * Returns the MQTT V5 type code of an MQTT V5 property. + * @param value an MQTT V5 property code. + * @return the MQTT V5 type code of the input property. -1 if the code was not found. + */ +LIBMQTT_API int MQTTProperty_getType(enum MQTTPropertyCodes value); + +/** + * The data for a length delimited string + */ +typedef struct +{ + int len; /**< the length of the string */ + char* data; /**< pointer to the string data */ +} MQTTLenString; + + +/** + * Structure to hold an MQTT version 5 property of any type + */ +typedef struct +{ + enum MQTTPropertyCodes identifier; /**< The MQTT V5 property id. A multi-byte integer. */ + /** The value of the property, as a union of the different possible types. */ + union { + unsigned char byte; /**< holds the value of a byte property type */ + unsigned short integer2; /**< holds the value of a 2 byte integer property type */ + unsigned int integer4; /**< holds the value of a 4 byte integer property type */ + struct { + MQTTLenString data; /**< The value of a string property, or the name of a user property. */ + MQTTLenString value; /**< The value of a user property. */ + }; + } value; +} MQTTProperty; + +/** + * MQTT version 5 property list + */ +typedef struct MQTTProperties +{ + int count; /**< number of property entries in the array */ + int max_count; /**< max number of properties that the currently allocated array can store */ + int length; /**< mbi: byte length of all properties */ + MQTTProperty *array; /**< array of properties */ +} MQTTProperties; + +#define MQTTProperties_initializer {0, 0, 0, NULL} + +/** + * Returns the length of the properties structure when serialized ready for network transmission. + * @param props an MQTT V5 property structure. + * @return the length in bytes of the properties when serialized. + */ +int MQTTProperties_len(MQTTProperties* props); + +/** + * Add a property pointer to the property array. There is no memory allocation. + * @param props The property list to add the property to. + * @param prop The property to add to the list. + * @return 0 on success, -1 on failure. + */ +LIBMQTT_API int MQTTProperties_add(MQTTProperties* props, const MQTTProperty* prop); + +/** + * Serialize the given property list to a character buffer, e.g. for writing to the network. + * @param pptr pointer to the buffer - move the pointer as we add data + * @param properties pointer to the property list, can be NULL + * @return whether the write succeeded or not: number of bytes written, or < 0 on failure. + */ +int MQTTProperties_write(char** pptr, const MQTTProperties* properties); + +/** + * Reads a property list from a character buffer into an array. + * @param properties pointer to the property list to be filled. Should be initalized but empty. + * @param pptr pointer to the character buffer. + * @param enddata pointer to the end of the character buffer so we don't read beyond. + * @return 1 if the properties were read successfully. + */ +int MQTTProperties_read(MQTTProperties* properties, char** pptr, char* enddata); + +/** + * Free all memory allocated to the property list, including any to individual properties. + * @param properties pointer to the property list. + */ +LIBMQTT_API void MQTTProperties_free(MQTTProperties* properties); + +/** + * Copy the contents of a property list, allocating additional memory if needed. + * @param props pointer to the property list. + * @return the duplicated property list. + */ +LIBMQTT_API MQTTProperties MQTTProperties_copy(const MQTTProperties* props); + +/** + * Checks if property list contains a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return 1 if found, 0 if not. + */ +LIBMQTT_API int MQTTProperties_hasProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the number of instances of a property id. Most properties can exist only once. + * User properties and subscription ids can exist more than once. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the number of times found. Can be 0. + */ +LIBMQTT_API int MQTTProperties_propertyCount(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property. The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValue(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property when it's not the only instance. + * The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValueAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +/** + * Returns a pointer to the property structure for a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns a pointer to the property structure for a specific property when it's not the only instance. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getPropertyAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +#endif /* MQTTPROPERTIES_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProtocol.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProtocol.h new file mode 100644 index 0000000..52bcd15 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProtocol.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - MQTT 3.1.1 updates + *******************************************************************************/ + +#if !defined(MQTTPROTOCOL_H) +#define MQTTPROTOCOL_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +typedef struct +{ + int socket; + Publications* p; +} pending_write; + + +typedef struct +{ + List publications; + unsigned int msgs_received; + unsigned int msgs_sent; + List pending_writes; /* for qos 0 writes not complete */ +} MQTTProtocol; + + +#include "MQTTProtocolOut.h" + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProtocolClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProtocolClient.h new file mode 100644 index 0000000..2d077af --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProtocolClient.h @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 updates + * Rong Xiang, Ian Craggs - C++ compatibility + * Ian Craggs - add debug definition of MQTTStrdup for when needed + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLCLIENT_H) +#define MQTTPROTOCOLCLIENT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Log.h" +#include "MQTTProtocol.h" +#include "Messages.h" +#include "MQTTProperties.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +int MQTTProtocol_startPublish(Clients* pubclient, Publish* publish, int qos, int retained, Messages** m); +Messages* MQTTProtocol_createMessage(Publish* publish, Messages** mm, int qos, int retained, int allocatePayload); +Publications* MQTTProtocol_storePublication(Publish* publish, int* len); +int messageIDCompare(void* a, void* b); +int MQTTProtocol_assignMsgId(Clients* client); +void MQTTProtocol_removePublication(Publications* p); +void Protocol_processPublication(Publish* publish, Clients* client, int allocatePayload); + +int MQTTProtocol_handlePublishes(void* pack, int sock); +int MQTTProtocol_handlePubacks(void* pack, int sock); +int MQTTProtocol_handlePubrecs(void* pack, int sock); +int MQTTProtocol_handlePubrels(void* pack, int sock); +int MQTTProtocol_handlePubcomps(void* pack, int sock); + +void MQTTProtocol_closeSession(Clients* c, int sendwill); +void MQTTProtocol_keepalive(START_TIME_TYPE); +void MQTTProtocol_retry(START_TIME_TYPE, int, int); +void MQTTProtocol_freeClient(Clients* client); +void MQTTProtocol_emptyMessageList(List* msgList); +void MQTTProtocol_freeMessageList(List* msgList); + +char* MQTTStrncpy(char *dest, const char* src, size_t num); +char* MQTTStrdup(const char* src); + +//#define MQTTStrdup(src) MQTTStrncpy(malloc(strlen(src)+1), src, strlen(src)+1) + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProtocolOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProtocolOut.h new file mode 100644 index 0000000..6a50155 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTProtocolOut.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - SNI support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLOUT_H) +#define MQTTPROTOCOLOUT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" +#include "Log.h" +#include "Messages.h" +#include "MQTTProtocol.h" +#include "MQTTProtocolClient.h" + +#define MQTT_DEFAULT_PORT 1883 +#define SECURE_MQTT_DEFAULT_PORT 8883 +#define WS_DEFAULT_PORT 80 + +size_t MQTTProtocol_addressPort(const char* uri, int* port, const char **topic, int default_port); +void MQTTProtocol_reconnect(const char* ip_address, Clients* client); +#if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#else +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#endif +int MQTTProtocol_handlePingresps(void* pack, int sock); +int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, int msgID, + MQTTSubscribe_options* opts, MQTTProperties* props); +int MQTTProtocol_handleSubacks(void* pack, int sock); +int MQTTProtocol_unsubscribe(Clients* client, List* topics, int msgID, MQTTProperties* props); +int MQTTProtocol_handleUnsubacks(void* pack, int sock); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTReasonCodes.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTReasonCodes.h new file mode 100644 index 0000000..2dc08ea --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTReasonCodes.h @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTREASONCODES_H) +#define MQTTREASONCODES_H + +#include "MQTTExportDeclarations.h" + +/** The MQTT V5 one byte reason code */ +enum MQTTReasonCodes { + MQTTREASONCODE_SUCCESS = 0, + MQTTREASONCODE_NORMAL_DISCONNECTION = 0, + MQTTREASONCODE_GRANTED_QOS_0 = 0, + MQTTREASONCODE_GRANTED_QOS_1 = 1, + MQTTREASONCODE_GRANTED_QOS_2 = 2, + MQTTREASONCODE_DISCONNECT_WITH_WILL_MESSAGE = 4, + MQTTREASONCODE_NO_MATCHING_SUBSCRIBERS = 16, + MQTTREASONCODE_NO_SUBSCRIPTION_FOUND = 17, + MQTTREASONCODE_CONTINUE_AUTHENTICATION = 24, + MQTTREASONCODE_RE_AUTHENTICATE = 25, + MQTTREASONCODE_UNSPECIFIED_ERROR = 128, + MQTTREASONCODE_MALFORMED_PACKET = 129, + MQTTREASONCODE_PROTOCOL_ERROR = 130, + MQTTREASONCODE_IMPLEMENTATION_SPECIFIC_ERROR = 131, + MQTTREASONCODE_UNSUPPORTED_PROTOCOL_VERSION = 132, + MQTTREASONCODE_CLIENT_IDENTIFIER_NOT_VALID = 133, + MQTTREASONCODE_BAD_USER_NAME_OR_PASSWORD = 134, + MQTTREASONCODE_NOT_AUTHORIZED = 135, + MQTTREASONCODE_SERVER_UNAVAILABLE = 136, + MQTTREASONCODE_SERVER_BUSY = 137, + MQTTREASONCODE_BANNED = 138, + MQTTREASONCODE_SERVER_SHUTTING_DOWN = 139, + MQTTREASONCODE_BAD_AUTHENTICATION_METHOD = 140, + MQTTREASONCODE_KEEP_ALIVE_TIMEOUT = 141, + MQTTREASONCODE_SESSION_TAKEN_OVER = 142, + MQTTREASONCODE_TOPIC_FILTER_INVALID = 143, + MQTTREASONCODE_TOPIC_NAME_INVALID = 144, + MQTTREASONCODE_PACKET_IDENTIFIER_IN_USE = 145, + MQTTREASONCODE_PACKET_IDENTIFIER_NOT_FOUND = 146, + MQTTREASONCODE_RECEIVE_MAXIMUM_EXCEEDED = 147, + MQTTREASONCODE_TOPIC_ALIAS_INVALID = 148, + MQTTREASONCODE_PACKET_TOO_LARGE = 149, + MQTTREASONCODE_MESSAGE_RATE_TOO_HIGH = 150, + MQTTREASONCODE_QUOTA_EXCEEDED = 151, + MQTTREASONCODE_ADMINISTRATIVE_ACTION = 152, + MQTTREASONCODE_PAYLOAD_FORMAT_INVALID = 153, + MQTTREASONCODE_RETAIN_NOT_SUPPORTED = 154, + MQTTREASONCODE_QOS_NOT_SUPPORTED = 155, + MQTTREASONCODE_USE_ANOTHER_SERVER = 156, + MQTTREASONCODE_SERVER_MOVED = 157, + MQTTREASONCODE_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158, + MQTTREASONCODE_CONNECTION_RATE_EXCEEDED = 159, + MQTTREASONCODE_MAXIMUM_CONNECT_TIME = 160, + MQTTREASONCODE_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161, + MQTTREASONCODE_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162 +}; + +/** + * Returns a printable string description of an MQTT V5 reason code. + * @param value an MQTT V5 reason code. + * @return the printable string description of the input reason code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTReasonCode_toString(enum MQTTReasonCodes value); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTSubscribeOpts.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTSubscribeOpts.h new file mode 100644 index 0000000..264e4d0 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTSubscribeOpts.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(SUBOPTS_H) +#define SUBOPTS_H + +/** The MQTT V5 subscribe options, apart from QoS which existed before V5. */ +typedef struct MQTTSubscribe_options +{ + /** The eyecatcher for this structure. Must be MQSO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0. + */ + int struct_version; + /** To not receive our own publications, set to 1. + * 0 is the original MQTT behaviour - all messages matching the subscription are received. + */ + unsigned char noLocal; + /** To keep the retain flag as on the original publish message, set to 1. + * If 0, defaults to the original MQTT behaviour where the retain flag is only set on + * publications sent by a broker if in response to a subscribe request. + */ + unsigned char retainAsPublished; + /** 0 - send retained messages at the time of the subscribe (original MQTT behaviour) + * 1 - send retained messages on subscribe only if the subscription is new + * 2 - do not send retained messages at all + */ + unsigned char retainHandling; +} MQTTSubscribe_options; + +#define MQTTSubscribe_options_initializer { {'M', 'Q', 'S', 'O'}, 0, 0, 0, 0 } + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTTime.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTTime.h new file mode 100644 index 0000000..8bd6860 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/MQTTTime.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + *******************************************************************************/ + +#if !defined(MQTTTIME_H) +#define MQTTTIME_H + +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#if WINVER >= _WIN32_WINNT_VISTA +#define START_TIME_TYPE ULONGLONG +#define START_TIME_ZERO 0 +#else +#define START_TIME_TYPE DWORD +#define START_TIME_ZERO 0 +#endif +#elif defined(AIX) +#define START_TIME_TYPE struct timespec +#define START_TIME_ZERO {0, 0} +#else +#include +#define START_TIME_TYPE struct timeval +#define START_TIME_ZERO {0, 0} +#endif + +#define ELAPSED_TIME_TYPE uint64_t +#define DIFF_TIME_TYPE int64_t + +void MQTTTime_sleep(ELAPSED_TIME_TYPE milliseconds); +START_TIME_TYPE MQTTTime_start_clock(void); +START_TIME_TYPE MQTTTime_now(void); +ELAPSED_TIME_TYPE MQTTTime_elapsed(START_TIME_TYPE milliseconds); +DIFF_TIME_TYPE MQTTTime_difftime(START_TIME_TYPE new, START_TIME_TYPE old); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Messages.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Messages.h new file mode 100644 index 0000000..58f5eae --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Messages.h @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MESSAGES_H) +#define MESSAGES_H + +#include "Log.h" + +const char* Messages_get(int, enum LOG_LEVELS); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/OsWrapper.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/OsWrapper.h new file mode 100644 index 0000000..96b629d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/OsWrapper.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016, 2017 logi.cals GmbH + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Gunter Raidl - timer support for VxWorks + * Rainer Poisel - reusability + *******************************************************************************/ + +#if !defined(OSWRAPPER_H) +#define OSWRAPPER_H + +#if defined(_WRS_KERNEL) +#include + +#define lstat stat + +typedef unsigned long useconds_t; +void usleep(useconds_t useconds); + +#define timersub(a, b, result) \ + do \ + { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) \ + { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000L; \ + } \ + } while (0) +#endif /* defined(_WRS_KERNEL) */ + +#endif /* OSWRAPPER_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/SHA1.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/SHA1.h new file mode 100644 index 0000000..3ae2f0a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/SHA1.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2018, 2019 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(SHA1_H) +#define SHA1_H + +#if defined(OPENSSL) +#include + +/** SHA-1 Digest Length */ +#define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH + +#else /* if defined(OPENSSL) */ + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +typedef struct SHA_CTX_S +{ + HCRYPTPROV hProv; + HCRYPTHASH hHash; +} SHA_CTX; +#else /* if defined(_WIN32) || defined(_WIN64) */ + +#include +typedef struct SHA_CTX_S { + uint32_t h[5]; + union { + uint32_t w[16]; + uint8_t buffer[64]; + }; + unsigned int size; + unsigned int total; +} SHA_CTX; +#endif /* else if defined(_WIN32) || defined(_WIN64) */ + +#include + +/** SHA-1 Digest Length (number of bytes in SHA1) */ +#define SHA1_DIGEST_LENGTH (160/8) + +/** + * Initializes the SHA1 hashing algorithm + * + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Update + * @see SHA1_Final + */ +int SHA1_Init(SHA_CTX *ctx); + +/** + * Updates a block to the SHA1 hash + * + * @param[in,out] ctx hashing context structure + * @param[in] data block of data to hash + * @param[in] len length of block to hash + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Update(SHA_CTX *ctx, const void *data, size_t len); + +/** + * Produce final SHA1 hash + * + * @param[out] md SHA1 hash produced (must be atleast + * @p SHA1_DIGEST_LENGTH in length) + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Final(unsigned char *md, SHA_CTX *ctx); + +#endif /* if defined(OPENSSL) */ +#endif /* SHA1_H */ + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/SSLSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/SSLSocket.h new file mode 100644 index 0000000..86273c8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/SSLSocket.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs, Allan Stockdill-Mander - initial implementation + * Ian Craggs - SNI support + * Ian Craggs - post connect checks and CApath + *******************************************************************************/ +#if !defined(SSLSOCKET_H) +#define SSLSOCKET_H + +#if defined(_WIN32) || defined(_WIN64) + #define ssl_mutex_type HANDLE +#else + #include + #include + #define ssl_mutex_type pthread_mutex_t +#endif + +#include +#include "SocketBuffer.h" +#include "Clients.h" + +#define URI_SSL "ssl://" + +/** if we should handle openssl initialization (bool_value == 1) or depend on it to be initalized externally (bool_value == 0) */ +void SSLSocket_handleOpensslInit(int bool_value); + +int SSLSocket_initialize(void); +void SSLSocket_terminate(void); +int SSLSocket_setSocketForSSL(networkHandles* net, MQTTClient_SSLOptions* opts, const char* hostname, size_t hostname_len); + +int SSLSocket_getch(SSL* ssl, int socket, char* c); +char *SSLSocket_getdata(SSL* ssl, int socket, size_t bytes, size_t* actual_len, int* rc); + +int SSLSocket_close(networkHandles* net); +int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +int SSLSocket_connect(SSL* ssl, int sock, const char* hostname, int verify, int (*cb)(const char *str, size_t len, void *u), void* u); + +int SSLSocket_getPendingRead(void); +int SSLSocket_continueWrite(pending_writes* pw); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Socket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Socket.h new file mode 100644 index 0000000..39a8158 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Socket.h @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + * Ian Craggs - async client updates + *******************************************************************************/ + +#if !defined(SOCKET_H) +#define SOCKET_H + +#include +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#include +#define MAXHOSTNAMELEN 256 +#if !defined(SSLSOCKET_H) +#undef EAGAIN +#define EAGAIN WSAEWOULDBLOCK +#undef EINTR +#define EINTR WSAEINTR +#undef EINPROGRESS +#define EINPROGRESS WSAEINPROGRESS +#undef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#undef ENOTCONN +#define ENOTCONN WSAENOTCONN +#undef ECONNRESET +#define ECONNRESET WSAECONNRESET +#undef ETIMEDOUT +#define ETIMEDOUT WAIT_TIMEOUT +#endif +#define ioctl ioctlsocket +#define socklen_t int +#else +#define INVALID_SOCKET SOCKET_ERROR +#include +#if !defined(_WRS_KERNEL) +#include +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define ULONG size_t +#endif + +#include "mutex_type.h" /* Needed for mutex_type */ + +/** socket operation completed successfully */ +#define TCPSOCKET_COMPLETE 0 +#if !defined(SOCKET_ERROR) + /** error in socket operation */ + #define SOCKET_ERROR -1 +#endif +/** must be the same as SOCKETBUFFER_INTERRUPTED */ +#define TCPSOCKET_INTERRUPTED -22 +#define SSL_FATAL -3 + +#if !defined(INET6_ADDRSTRLEN) +#define INET6_ADDRSTRLEN 46 /** only needed for gcc/cygwin on windows */ +#endif + + +#if !defined(max) +#define max(A,B) ( (A) > (B) ? (A):(B)) +#endif + +#include "LinkedList.h" + +/* + * Network write buffers for an MQTT packet + */ +typedef struct +{ + int count; /**> number of buffers/buflens/frees */ + char** buffers; /**> array of byte buffers */ + size_t* buflens; /**> array of lengths of buffers */ + int* frees; /**> array of flags indicating whether each buffer needs to be freed */ + uint8_t mask[4]; /**> websocket mask used to mask the buffer data, if any */ +} PacketBuffers; + + +/** + * Structure to hold all socket data for the module + */ +typedef struct +{ + fd_set rset, /**< socket read set (see select doc) */ + rset_saved; /**< saved socket read set */ + int maxfdp1; /**< max descriptor used +1 (again see select doc) */ + List* clientsds; /**< list of client socket descriptors */ + ListElement* cur_clientsds; /**< current client socket descriptor (iterator) */ + List* connect_pending; /**< list of sockets for which a connect is pending */ + List* write_pending; /**< list of sockets for which a write is pending */ + fd_set pending_wset; /**< socket pending write set for select */ +} Sockets; + + +void Socket_outInitialize(void); +void Socket_outTerminate(void); +int Socket_getReadySocket(int more_work, struct timeval *tp, mutex_type mutex, int* rc); +int Socket_getch(int socket, char* c); +char *Socket_getdata(int socket, size_t bytes, size_t* actual_len, int* rc); +int Socket_putdatas(int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +void Socket_close(int socket); +#if defined(__GNUC__) && defined(__linux__) +/* able to use GNU's getaddrinfo_a to make timeouts possible */ +int Socket_new(const char* addr, size_t addr_len, int port, int* socket, long timeout); +#else +int Socket_new(const char* addr, size_t addr_len, int port, int* socket); +#endif + +int Socket_noPendingWrites(int socket); +char* Socket_getpeer(int sock); + +void Socket_addPendingWrite(int socket); +void Socket_clearPendingWrite(int socket); + +typedef void Socket_writeComplete(int socket, int rc); +void Socket_setWriteCompleteCallback(Socket_writeComplete*); + +#endif /* SOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/SocketBuffer.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/SocketBuffer.h new file mode 100644 index 0000000..0fc7d6e --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/SocketBuffer.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + *******************************************************************************/ + +#if !defined(SOCKETBUFFER_H) +#define SOCKETBUFFER_H + +#if defined(_WIN32) || defined(_WIN64) +#include +#else +#include +#endif + +#if defined(OPENSSL) +#include +#endif + +#if defined(_WIN32) || defined(_WIN64) + typedef WSABUF iobuf; +#else + typedef struct iovec iobuf; +#endif + +typedef struct +{ + int socket; + unsigned int index; + size_t headerlen; + char fixed_header[5]; /**< header plus up to 4 length bytes */ + size_t buflen, /**< total length of the buffer */ + datalen; /**< current length of data in buf */ + char* buf; +} socket_queue; + +typedef struct +{ + int socket, count; + size_t total; +#if defined(OPENSSL) + SSL* ssl; +#endif + size_t bytes; + iobuf iovecs[5]; + int frees[5]; +} pending_writes; + +#define SOCKETBUFFER_COMPLETE 0 +#if !defined(SOCKET_ERROR) + #define SOCKET_ERROR -1 +#endif +#define SOCKETBUFFER_INTERRUPTED -22 /* must be the same value as TCPSOCKET_INTERRUPTED */ + +int SocketBuffer_initialize(void); +void SocketBuffer_terminate(void); +void SocketBuffer_cleanup(int socket); +char* SocketBuffer_getQueuedData(int socket, size_t bytes, size_t* actual_len); +int SocketBuffer_getQueuedChar(int socket, char* c); +void SocketBuffer_interrupted(int socket, size_t actual_len); +char* SocketBuffer_complete(int socket); +void SocketBuffer_queueChar(int socket, char c); + +#if defined(OPENSSL) +int SocketBuffer_pendingWrite(int socket, SSL* ssl, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#else +int SocketBuffer_pendingWrite(int socket, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#endif +pending_writes* SocketBuffer_getWrite(int socket); +int SocketBuffer_writeComplete(int socket); +pending_writes* SocketBuffer_updateWrite(int socket, char* topic, char* payload); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/StackTrace.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/StackTrace.h new file mode 100644 index 0000000..c4f0d43 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/StackTrace.h @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#ifndef STACKTRACE_H_ +#define STACKTRACE_H_ + +#if defined(HIGH_PERFORMANCE) +#define NOSTACKTRACE 1 +#endif + +#include +#include "Log.h" +#include "Thread.h" + +#if defined(NOSTACKTRACE) +#define FUNC_ENTRY +#define FUNC_ENTRY_NOLOG +#define FUNC_ENTRY_MED +#define FUNC_ENTRY_MAX +#define FUNC_EXIT +#define FUNC_EXIT_NOLOG +#define FUNC_EXIT_MED +#define FUNC_EXIT_MAX +#define FUNC_EXIT_RC(x) +#define FUNC_EXIT_MED_RC(x) +#define FUNC_EXIT_MAX_RC(x) +#else +#if defined(_WIN32) || defined(_WIN64) +#define inline __inline +#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM) +#else +#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM) +#endif +#endif + +void StackTrace_entry(const char* name, int line, enum LOG_LEVELS trace); +void StackTrace_exit(const char* name, int line, void* return_value, enum LOG_LEVELS trace); + +void StackTrace_printStack(FILE* dest); +char* StackTrace_get(thread_id_type, char* buf, int bufsize); + +#endif /* STACKTRACE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Thread.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Thread.h new file mode 100644 index 0000000..29903f5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Thread.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + * Ian Craggs, Allan Stockdill-Mander - async client updates + * Ian Craggs - fix for bug #420851 + * Ian Craggs - change MacOS semaphore implementation + *******************************************************************************/ + +#if !defined(THREAD_H) +#define THREAD_H + +#include "MQTTExportDeclarations.h" + +#include "MQTTClient.h" + +#include "mutex_type.h" /* Needed for mutex_type */ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define thread_type HANDLE + #define thread_id_type DWORD + #define thread_return_type DWORD + #define thread_fn LPTHREAD_START_ROUTINE + #define cond_type HANDLE + #define sem_type HANDLE + #undef ETIMEDOUT + #define ETIMEDOUT WSAETIMEDOUT +#else + #include + + #define thread_type pthread_t + #define thread_id_type pthread_t + #define thread_return_type void* + typedef thread_return_type (*thread_fn)(void*); + typedef struct { pthread_cond_t cond; pthread_mutex_t mutex; } cond_type_struct; + typedef cond_type_struct *cond_type; + #if defined(OSX) + #include + typedef dispatch_semaphore_t sem_type; + #else + #include + typedef sem_t *sem_type; + #endif + + cond_type Thread_create_cond(int*); + int Thread_signal_cond(cond_type); + int Thread_wait_cond(cond_type condvar, int timeout); + int Thread_destroy_cond(cond_type); +#endif + +LIBMQTT_API thread_type Thread_start(thread_fn, void*); + +LIBMQTT_API mutex_type Thread_create_mutex(int*); +LIBMQTT_API int Thread_lock_mutex(mutex_type); +LIBMQTT_API int Thread_unlock_mutex(mutex_type); +int Thread_destroy_mutex(mutex_type); + +LIBMQTT_API thread_id_type Thread_getid(); + +sem_type Thread_create_sem(int*); +int Thread_wait_sem(sem_type sem, int timeout); +int Thread_check_sem(sem_type sem); +int Thread_post_sem(sem_type sem); +int Thread_destroy_sem(sem_type sem); + + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Tree.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Tree.h new file mode 100644 index 0000000..dfd70ab --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/Tree.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + + +#if !defined(TREE_H) +#define TREE_H + +#include /* for size_t definition */ + +/*BE +defm defTree(T) // macro to define a tree + +def T concat Node +{ + n32 ptr T concat Node "parent" + n32 ptr T concat Node "left" + n32 ptr T concat Node "right" + n32 ptr T id2str(T) + n32 suppress "size" +} + + +def T concat Tree +{ + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + n32 dec "count" + n32 dec suppress "size" +} + +endm + +defTree(INT) +defTree(STRING) +defTree(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct NodeStruct +{ + struct NodeStruct *parent, /**< pointer to parent tree node, in case we need it */ + *child[2]; /**< pointers to child tree nodes 0 = left, 1 = right */ + void* content; /**< pointer to element content */ + size_t size; /**< size of content */ + unsigned int red : 1; +} Node; + + +/** + * Structure to hold all data for one tree + */ +typedef struct +{ + struct + { + Node *root; /**< root node pointer */ + int (*compare)(void*, void*, int); /**< comparison function */ + } index[2]; + int indexes, /**< no of indexes into tree */ + count; /**< no of items */ + size_t size; /**< heap storage used */ + unsigned int heap_tracking : 1; /**< switch on heap tracking for this tree? */ + unsigned int allow_duplicates : 1; /**< switch to allow duplicate entries */ +} Tree; + + +Tree* TreeInitialize(int(*compare)(void*, void*, int)); +void TreeInitializeNoMalloc(Tree* aTree, int(*compare)(void*, void*, int)); +void TreeAddIndex(Tree* aTree, int(*compare)(void*, void*, int)); + +void* TreeAdd(Tree* aTree, void* content, size_t size); + +void* TreeRemove(Tree* aTree, void* content); + +void* TreeRemoveKey(Tree* aTree, void* key); +void* TreeRemoveKeyIndex(Tree* aTree, void* key, int index); + +void* TreeRemoveNodeIndex(Tree* aTree, Node* aNode, int index); + +void TreeFree(Tree* aTree); + +Node* TreeFind(Tree* aTree, void* key); +Node* TreeFindIndex(Tree* aTree, void* key, int index); + +Node* TreeNextElement(Tree* aTree, Node* curnode); + +int TreeIntCompare(void* a, void* b, int); +int TreePtrCompare(void* a, void* b, int); +int TreeStringCompare(void* a, void* b, int); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/VersionInfo.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/VersionInfo.h new file mode 100644 index 0000000..b3b3e78 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/VersionInfo.h @@ -0,0 +1,7 @@ +#ifndef VERSIONINFO_H +#define VERSIONINFO_H + +#define BUILD_TIMESTAMP "2021-02-11 12:10" +#define CLIENT_VERSION "1.3.8" + +#endif /* VERSIONINFO_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/WebSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/WebSocket.h new file mode 100644 index 0000000..e9f5765 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/WebSocket.h @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2018, 2020 Wind River Systems, Inc. and others. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(WEBSOCKET_H) +#define WEBSOCKET_H + +#include "MQTTPacket.h" + +/** + * WebSocket op codes + * @{ + */ +#define WebSocket_OP_CONTINUE 0x0 /* 0000 - continue frame */ +#define WebSocket_OP_TEXT 0x1 /* 0001 - text frame */ +#define WebSocket_OP_BINARY 0x2 /* 0010 - binary frame */ +#define WebSocket_OP_CLOSE 0x8 /* 1000 - close frame */ +#define WebSocket_OP_PING 0x9 /* 1001 - ping frame */ +#define WebSocket_OP_PONG 0xA /* 1010 - pong frame */ +/** @} */ + +/** + * Various close status codes + * @{ + */ +#define WebSocket_CLOSE_NORMAL 1000 +#define WebSocket_CLOSE_GOING_AWAY 1001 +#define WebSocket_CLOSE_PROTOCOL_ERROR 1002 +#define WebSocket_CLOSE_UNKNOWN_DATA 1003 +#define WebSocket_CLOSE_RESERVED 1004 +#define WebSocket_CLOSE_NO_STATUS_CODE 1005 /* reserved: not to be used */ +#define WebSocket_CLOSE_ABNORMAL 1006 /* reserved: not to be used */ +#define WebSocket_CLOSE_BAD_DATA 1007 +#define WebSocket_CLOSE_POLICY 1008 +#define WebSocket_CLOSE_MSG_TOO_BIG 1009 +#define WebSocket_CLOSE_NO_EXTENSION 1010 +#define WebScoket_CLOSE_UNEXPECTED 1011 +#define WebSocket_CLOSE_TLS_FAIL 1015 /* reserved: not be used */ +/** @} */ + +/* closes a websocket connection */ +void WebSocket_close(networkHandles *net, int status_code, const char *reason); + +/* sends upgrade request */ +int WebSocket_connect(networkHandles *net, const char *uri); + +/* obtain data from network socket */ +int WebSocket_getch(networkHandles *net, char* c); +char *WebSocket_getdata(networkHandles *net, size_t bytes, size_t* actual_len); +size_t WebSocket_framePos(); +void WebSocket_framePosSeekTo(size_t); + +/* send data out, in websocket format only if required */ +int WebSocket_putdatas(networkHandles* net, char** buf0, size_t* buf0len, PacketBuffers* bufs); + +/* releases any resources used by the websocket system */ +void WebSocket_terminate(void); + +/* handles websocket upgrade request */ +int WebSocket_upgrade(networkHandles *net); + +/* Notify the IP address and port of the endpoint to proxy, and wait connection to endpoint */ +int WebSocket_proxy_connect( networkHandles *net, int ssl, const char *hostname); + +#endif /* WEBSOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/mutex_type.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/mutex_type.h new file mode 100644 index 0000000..1e4b9e5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/mutex_type.h @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + *******************************************************************************/ +#if !defined(_MUTEX_TYPE_H_) +#define _MUTEX_TYPE_H_ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define mutex_type HANDLE +#else + #include + #define mutex_type pthread_mutex_t* +#endif + +#endif /* _MUTEX_TYPE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/utf-8.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/utf-8.h new file mode 100644 index 0000000..a7a4270 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/include/utf-8.h @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(UTF8_H) +#define UTF8_H + +int UTF8_validate(int len, const char *data); +int UTF8_validateString(const char* string); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libAR.a new file mode 100644 index 0000000..41d916b Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libOpenSSL_s.a new file mode 100644 index 0000000..71dcb72 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libPahoMQTT_s.a new file mode 100644 index 0000000..e8464c9 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libar_posix_s.a new file mode 100644 index 0000000..291664c Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.72.0/SG4/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/Binary.lby b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/Binary.lby new file mode 100644 index 0000000..a92156a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/Binary.lby @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libAR.a new file mode 100644 index 0000000..235f5d6 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libOpenSSL_s.a new file mode 100644 index 0000000..a50c3cc Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libPahoMQTT_s.a new file mode 100644 index 0000000..822b826 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libar_posix_s.a new file mode 100644 index 0000000..8b34d35 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/Arm/libar_posix_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Base64.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Base64.h new file mode 100644 index 0000000..7022ce8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Base64.h @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2018 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(BASE64_H) +#define BASE64_H + +/** type for size of a buffer, it saves passing around @p size_t (unsigned long long or unsigned long int) */ +typedef unsigned int b64_size_t; +/** type for raw base64 data */ +typedef unsigned char b64_data_t; + +/** + * Decodes base64 data + * + * @param[out] out decoded data + * @param[in] out_len length of output buffer + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the amount of data decoded + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_decode( b64_data_t *out, b64_size_t out_len, + const char *in, b64_size_t in_len ); + +/** + * Size of buffer required to decode base64 data + * + * @param[in] in base64 string to decode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the decoded string would require + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_decodeLength( const char *in, b64_size_t in_len ); + +/** + * Encodes base64 data + * + * @param[out] out encode base64 string + * @param[in] out_len length of output buffer + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the amount of data encoded + * + * @see Base64_decode + * @see Base64_encodeLength + */ +b64_size_t Base64_encode( char *out, b64_size_t out_len, + const b64_data_t *in, b64_size_t in_len ); + +/** + * Size of buffer required to encode base64 data + * + * @param[in] in raw data to encode + * @param[in] in_len length of input buffer + * + * @return the size of buffer the encoded string would require + * + * @see Base64_decodeLength + * @see Base64_encode + */ +b64_size_t Base64_encodeLength( const b64_data_t *in, b64_size_t in_len ); + +#endif /* BASE64_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Clients.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Clients.h new file mode 100644 index 0000000..a3ddb1f --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Clients.h @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - add SSL support + * Ian Craggs - fix for bug 413429 - connectionLost not called + * Ian Craggs - change will payload to binary + * Ian Craggs - password to binary + * Ian Craggs - MQTT 5 support + *******************************************************************************/ + +#if !defined(CLIENTS_H) +#define CLIENTS_H + +#include +#include "MQTTTime.h" +#if defined(OPENSSL) +#if defined(_WIN32) || defined(_WIN64) +#include +#endif +#include +#endif +#include "MQTTClient.h" +#include "LinkedList.h" +#include "MQTTClientPersistence.h" + +/** + * Stored publication data to minimize copying + */ +typedef struct +{ + char *topic; + int topiclen; + char* payload; + int payloadlen; + int refcount; + uint8_t mask[4]; +} Publications; + +/** + * Client publication message data + */ +typedef struct +{ + int qos; + int retain; + int msgid; + int MQTTVersion; + MQTTProperties properties; + Publications *publish; + START_TIME_TYPE lastTouch; /**> used for retry and expiry */ + char nextMessageType; /**> PUBREC, PUBREL, PUBCOMP */ + int len; /**> length of the whole structure+data */ +} Messages; + +/** + * Client will message data + */ +typedef struct +{ + char *topic; + int payloadlen; + void *payload; + int retained; + int qos; +} willMessages; + +typedef struct +{ + int socket; + START_TIME_TYPE lastSent; + START_TIME_TYPE lastReceived; + START_TIME_TYPE lastPing; +#if defined(OPENSSL) + SSL* ssl; + SSL_CTX* ctx; + char *https_proxy; + char *https_proxy_auth; +#endif + char *http_proxy; + char *http_proxy_auth; + int websocket; /**< socket has been upgraded to use web sockets */ + char *websocket_key; + const MQTTClient_nameValue* httpHeaders; +} networkHandles; + + +/* connection states */ +/** no connection in progress, see connected value */ +#define NOT_IN_PROGRESS 0x0 +/** TCP connection in progress */ +#define TCP_IN_PROGRESS 0x1 +/** SSL connection in progress */ +#define SSL_IN_PROGRESS 0x2 +/** Websocket connection in progress */ +#define WEBSOCKET_IN_PROGRESS 0x3 +/** TCP completed, waiting for MQTT ACK */ +#define WAIT_FOR_CONNACK 0x4 +/** Proxy connection in progress */ +#define PROXY_CONNECT_IN_PROGRESS 0x5 +/** Disconnecting */ +#define DISCONNECTING -2 + +/** + * Data related to one client + */ +typedef struct +{ + char* clientID; /**< the string id of the client */ + const char* username; /**< MQTT v3.1 user name */ + int passwordlen; /**< MQTT password length */ + const void* password; /**< MQTT v3.1 binary password */ + unsigned int cleansession : 1; /**< MQTT V3 clean session flag */ + unsigned int cleanstart : 1; /**< MQTT V5 clean start flag */ + unsigned int connected : 1; /**< whether it is currently connected */ + unsigned int good : 1; /**< if we have an error on the socket we turn this off */ + unsigned int ping_outstanding : 1; + signed int connect_state : 4; + networkHandles net; /**< network info for this client */ + int msgID; /**< the MQTT message id */ + int keepAliveInterval; /**< the MQTT keep alive interval */ + int retryInterval; + int maxInflightMessages; /**< the max number of inflight outbound messages we allow */ + willMessages* will; /**< the MQTT will message, if any */ + List* inboundMsgs; /**< inbound in flight messages */ + List* outboundMsgs; /**< outbound in flight messages */ + List* messageQueue; /**< inbound complete but undelivered messages */ + unsigned int qentry_seqno; + void* phandle; /**< the persistence handle */ + MQTTClient_persistence* persistence; /**< a persistence implementation */ + MQTTPersistence_beforeWrite* beforeWrite; /**< persistence write callback */ + MQTTPersistence_afterRead* afterRead; /**< persistence read callback */ + void* beforeWrite_context; /**< context to be used with the persistence beforeWrite callbacks */ + void* afterRead_context; /**< context to be used with the persistence afterRead callback */ + void* context; /**< calling context - used when calling disconnect_internal */ + int MQTTVersion; /**< the version of MQTT being used, 3, 4 or 5 */ + int sessionExpiry; /**< MQTT 5 session expiry */ + char* httpProxy; /**< HTTP proxy for websockets */ + char* httpsProxy; /**< HTTPS proxy for websockets */ +#if defined(OPENSSL) + MQTTClient_SSLOptions *sslopts; /**< the SSL/TLS connect options */ + SSL_SESSION* session; /**< SSL session pointer for fast handhake */ +#endif +} Clients; + +int clientIDCompare(void* a, void* b); +int clientSocketCompare(void* a, void* b); + +/** + * Configuration data related to all clients + */ +typedef struct +{ + const char* version; + List* clients; +} ClientStates; + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Heap.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Heap.h new file mode 100644 index 0000000..f89a760 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Heap.h @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - use tree data structure instead of list + *******************************************************************************/ + + +#if !defined(HEAP_H) +#define HEAP_H + +#if defined(HIGH_PERFORMANCE) +#define NO_HEAP_TRACKING 1 +#endif + +#define PAHO_MEMORY_ERROR -99 + +#include "MQTTExportDeclarations.h" + +#include +#include + +#if !defined(NO_HEAP_TRACKING) + +#if !defined(TREE_C) +/** + * redefines malloc to use "mymalloc" so that heap allocation can be tracked + * @param x the size of the item to be allocated + * @return the pointer to the item allocated, or NULL + */ +#define malloc(x) mymalloc(__FILE__, __LINE__, x) + +/** + * redefines realloc to use "myrealloc" so that heap allocation can be tracked + * @param a the heap item to be reallocated + * @param b the new size of the item + * @return the new pointer to the heap item + */ +#define realloc(a, b) myrealloc(__FILE__, __LINE__, a, b) + +/** + * redefines free to use "myfree" so that heap allocation can be tracked + * @param x the size of the item to be freed + */ +#define free(x) myfree(__FILE__, __LINE__, x) + +#endif + +/** + * Information about the state of the heap. + */ +typedef struct +{ + size_t current_size; /**< current size of the heap in bytes */ + size_t max_size; /**< max size the heap has reached in bytes */ +} heap_info; + +#if defined(__cplusplus) + extern "C" { +#endif + +void* mymalloc(char*, int, size_t size); +void* myrealloc(char*, int, void* p, size_t size); +void myfree(char*, int, void* p); + +void Heap_scan(FILE* file); +int Heap_initialize(void); +void Heap_terminate(void); +LIBMQTT_API heap_info* Heap_get_info(void); +int HeapDump(FILE* file); +int HeapDumpString(FILE* file, char* str); +void* Heap_findItem(void* p); +void Heap_unlink(char* file, int line, void* p); +#ifdef __cplusplus + } +#endif + +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/LinkedList.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/LinkedList.h new file mode 100644 index 0000000..e390012 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/LinkedList.h @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + * Ian Craggs - change size types from int to size_t + *******************************************************************************/ + +#if !defined(LINKEDLIST_H) +#define LINKEDLIST_H + +#include /* for size_t definition */ + +/*BE +defm defList(T) + +def T concat Item +{ + at 4 + n32 ptr T concat Item suppress "next" + at 0 + n32 ptr T concat Item suppress "prev" + at 8 + n32 ptr T id2str(T) +} + +def T concat List +{ + n32 ptr T concat Item suppress "first" + n32 ptr T concat Item suppress "last" + n32 ptr T concat Item suppress "current" + n32 dec "count" + n32 suppress "size" +} +endm + +defList(INT) +defList(STRING) +defList(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct ListElementStruct +{ + struct ListElementStruct *prev, /**< pointer to previous list element */ + *next; /**< pointer to next list element */ + void* content; /**< pointer to element content */ +} ListElement; + + +/** + * Structure to hold all data for one list + */ +typedef struct +{ + ListElement *first, /**< first element in the list */ + *last, /**< last element in the list */ + *current; /**< current element in the list, for iteration */ + int count; /**< no of items */ + size_t size; /**< heap storage used */ +} List; + +void ListZero(List*); +List* ListInitialize(void); + +ListElement* ListAppend(List* aList, void* content, size_t size); +void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, size_t size); +ListElement* ListInsert(List* aList, void* content, size_t size, ListElement* index); + +int ListRemove(List* aList, void* content); +int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*)); +void* ListDetachHead(List* aList); +int ListRemoveHead(List* aList); +void* ListPopTail(List* aList); + +int ListDetach(List* aList, void* content); +int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*)); + +void ListFree(List* aList); +void ListEmpty(List* aList); +void ListFreeNoContent(List* aList); + +ListElement* ListNextElement(List* aList, ListElement** pos); +ListElement* ListPrevElement(List* aList, ListElement** pos); + +ListElement* ListFind(List* aList, void* content); +ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*)); + +int intcompare(void* a, void* b); +int stringcompare(void* a, void* b); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Log.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Log.h new file mode 100644 index 0000000..102e31d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Log.h @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - updates for the async client + *******************************************************************************/ + +#if !defined(LOG_H) +#define LOG_H + +/*BE +map LOG_LEVELS +{ + "TRACE_MAXIMUM" 1 + "TRACE_MEDIUM" 2 + "TRACE_MINIMUM" 3 + "TRACE_PROTOCOL" 4 + + "ERROR" 5 + "SEVERE" 6 + "FATAL" 7 +} +BE*/ + +enum LOG_LEVELS { + INVALID_LEVEL = -1, + TRACE_MAXIMUM = 1, + TRACE_MEDIUM, + TRACE_MINIMUM, + TRACE_PROTOCOL, + LOG_ERROR, + LOG_SEVERE, + LOG_FATAL, +}; + + +/*BE +def trace_settings_type +{ + n32 map LOG_LEVELS "trace_level" + n32 dec "max_trace_entries" + n32 dec "trace_output_level" +} +BE*/ +typedef struct +{ + enum LOG_LEVELS trace_level; /**< trace level */ + int max_trace_entries; /**< max no of entries in the trace buffer */ + enum LOG_LEVELS trace_output_level; /**< trace level to output to destination */ +} trace_settings_type; + +extern trace_settings_type trace_settings; + +#define LOG_PROTOCOL TRACE_PROTOCOL +#define TRACE_MAX TRACE_MAXIMUM +#define TRACE_MIN TRACE_MINIMUM +#define TRACE_MED TRACE_MEDIUM + +typedef struct +{ + const char* name; + const char* value; +} Log_nameValue; + +int Log_initialize(Log_nameValue*); +void Log_terminate(void); + +void Log(enum LOG_LEVELS, int, const char *, ...); +void Log_stackTrace(enum LOG_LEVELS, int, int, int, const char*, int, int*); + +typedef void Log_traceCallback(enum LOG_LEVELS level, const char *message); +void Log_setTraceCallback(Log_traceCallback* callback); +void Log_setTraceLevel(enum LOG_LEVELS level); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTAsync.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTAsync.h new file mode 100644 index 0000000..f728ba5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTAsync.h @@ -0,0 +1,2345 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation + * Ian Craggs, Allan Stockdill-Mander - SSL connections + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - fix for bug 444103 - success/failure callbacks not invoked + * Ian Craggs - automatic reconnect and offline buffering (send while disconnected) + * Ian Craggs - binary will message + * Ian Craggs - binary password + * Ian Craggs - remove const on eyecatchers #168 + * Ian Craggs - MQTT 5.0 + *******************************************************************************/ + +/********************************************************************/ + +/** + * @cond MQTTAsync_main + * @mainpage Asynchronous MQTT client library for C + * + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An Asynchronous MQTT client library for C. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the Asynchronous MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions
  • + *
  • Connect the client to an MQTT server
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref publish
  • + *
  • @ref subscribe
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
  • @ref auto_reconnect
  • + *
  • @ref offline_publish
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTASYNC_H) +#define MQTTASYNC_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTASYNC_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTASYNC_FAILURE -1 + +/* error code -2 is MQTTAsync_PERSISTENCE_ERROR */ + +#define MQTTASYNC_PERSISTENCE_ERROR -2 + +/** + * Return code: The client is disconnected. + */ +#define MQTTASYNC_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTASYNC_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTASYNC_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTASYNC_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTASYNC_BAD_STRUCTURE -8 +/** + * Return code: A qos parameter is not 0, 1 or 2 + */ +#define MQTTASYNC_BAD_QOS -9 +/** + * Return code: All 65535 MQTT msgids are being used + */ +#define MQTTASYNC_NO_MORE_MSGIDS -10 +/** + * Return code: the request is being discarded when not complete + */ +#define MQTTASYNC_OPERATION_INCOMPLETE -11 +/** + * Return code: no more messages can be buffered + */ +#define MQTTASYNC_MAX_BUFFERED_MESSAGES -12 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTASYNC_SSL_NOT_SUPPORTED -13 + /** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if the TLS version of the library + * is linked with. + */ +#define MQTTASYNC_BAD_PROTOCOL -14 + /** + * Return code: don't use options for another version of MQTT + */ + #define MQTTASYNC_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the client's version of MQTT + */ + #define MQTTASYNC_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic + */ + #define MQTTASYNC_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 +/** + * MQTT version to connect with: 5 + */ +#define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTAsync_init_options; + +#define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt (0) + */ +LIBMQTT_API void MQTTAsync_global_init(MQTTAsync_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTAsync_create(). + */ +typedef void* MQTTAsync; +/** + * A value representing an MQTT message. A token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTAsync_publish(), + * MQTTAsync_publishMessage(), + * MQTTAsync_deliveryComplete(), and + * MQTTAsync_getPendingTokens()). + */ +typedef int MQTTAsync_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTAsync_publishMessage(), + * MQTTAsync_publish(), MQTTAsync_receive(), MQTTAsync_freeMessage() + * and MQTTAsync_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. This is an output parameter only. + */ + int dup; + /** The message identifier is reserved for internal use by the + * MQTT client and server. It is an output parameter only - writing + * to it will serve no purpose. It contains the MQTT message id of + * an incoming publish message. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTAsync_message; + +#define MQTTAsync_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTAsync_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTAsync_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTAsync_freeMessage must be called. + * To free the topic name storage, ::MQTTAsync_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTAsync_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTAsync_messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages to the server. The function is + * registered with the client library by passing it as an argument to MQTTAsync_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTAsync_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param token The ::MQTTAsync_token associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the tokens returned from calls to + * MQTTAsync_send() and MQTTAsync_sendMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTAsync_deliveryComplete(void* context, MQTTAsync_token token); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTAsync_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connectionLost(void* context, char* cause); + + +/** + * This is a callback function, which will be called when the client + * library successfully connects. This is superfluous when the connection + * is made in response to a MQTTAsync_connect call, because the onSuccess + * callback can be used. It is intended for use when automatic reconnect + * is enabled, so that when a reconnection attempt succeeds in the background, + * the application is notified and can take any required actions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_connected(void* context, char* cause); + +/** + * This is a callback function, which will be called when the client + * library receives a disconnect packet. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * MQTTAsync_setCallbacks(), which contains any application-specific context. + * @param properties the properties in the disconnect packet. + * @param properties the reason code from the disconnect packet + * Currently, cause is always set to NULL. + */ +typedef void MQTTAsync_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTAsync_disconnected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDisconnected(MQTTAsync handle, void* context, MQTTAsync_disconnected* co); + +/** The connect options that can be updated before an automatic reconnect. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQCD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name parameter. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + const char* username; + /** + * The password parameter of the MQTT authentication. + * Set data to NULL to remove. To change, allocate new + * storage with ::MQTTAsync_allocate - this will then be free later by the library. + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; +} MQTTAsync_connectData; + +#define MQTTAsync_connectData_initializer {{'M', 'Q', 'C', 'D'}, 0, NULL, {0, NULL}} + +/** + * This is a callback function which will allow the client application to update the + * connection data. + * @param data The connection data which can be modified by the application. + * @return Return a non-zero value to update the connect data, zero to keep the same data. + */ +typedef int MQTTAsync_updateConnectOptions(void* context, MQTTAsync_connectData* data); + +/** + * Sets the MQTTAsync_updateConnectOptions() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_updateConnectOptions() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setUpdateConnectOptions(MQTTAsync handle, void* context, MQTTAsync_updateConnectOptions* co); + +/** + * Sets the MQTTPersistence_beforeWrite() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setBeforePersistenceWrite(MQTTAsync handle, void* context, MQTTPersistence_beforeWrite* co); + + +/** + * Sets the MQTTPersistence_afterRead() callback function for a client. + * @param handle A valid client handle from a successful call to MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback function to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTPersistence_beforeWrite() callback + * function. NULL removes the callback setting. + */ +LIBMQTT_API int MQTTAsync_setAfterPersistenceRead(MQTTAsync handle, void* context, MQTTPersistence_afterRead* co); + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** A numeric code identifying the error. */ + int code; + /** Optional text explaining the error. Can be NULL. */ + const char *message; +} MQTTAsync_failureData; + + +/** The data returned on completion of an unsuccessful API call in the response callback onFailure. */ +typedef struct +{ + /** The eyecatcher for this structure. Will be MQFD. */ + char struct_id[4]; + /** The version number of this structure. Will be 0 */ + int struct_version; + /** A token identifying the failed request. */ + MQTTAsync_token token; + /** The MQTT reason code returned. */ + enum MQTTReasonCodes reasonCode; + /** The MQTT properties on the ack, if any. */ + MQTTProperties properties; + /** A numeric code identifying the MQTT client library error. */ + int code; + /** Optional further text explaining the error. Can be NULL. */ + const char *message; + /** Packet type on which the failure occurred - used for publish QoS 1/2 exchanges*/ + int packet_type; +} MQTTAsync_failureData5; + +#define MQTTAsync_failureData5_initializer {{'M', 'Q', 'F', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, 0, NULL} + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribe, the granted QoS of the subscription returned by the server. + * Also for subscribeMany, if only 1 subscription was requested. */ + int qos; + /** For subscribeMany, if more than one subscription was requested, + * the list of granted QoSs of the subscriptions returned by the server. */ + int* qosList; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + } alt; +} MQTTAsync_successData; + + +/** The data returned on completion of a successful API call in the response callback onSuccess. */ +typedef struct +{ + char struct_id[4]; /**< The eyecatcher for this structure. Will be MQSD. */ + int struct_version; /**< The version number of this structure. Will be 0 */ + /** A token identifying the successful request. Can be used to refer to the request later. */ + MQTTAsync_token token; + enum MQTTReasonCodes reasonCode; /**< MQTT V5 reason code returned */ + MQTTProperties properties; /**< MQTT V5 properties returned, if any */ + /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */ + union + { + /** For subscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } sub; + /** For publish, the message being sent to the server. */ + struct + { + MQTTAsync_message message; /**< the message being sent to the server */ + char* destinationName; /**< the topic destination for the message */ + } pub; + /* For connect, the server connected to, MQTT version used, and sessionPresent flag */ + struct + { + char* serverURI; /**< the connection string of the server */ + int MQTTVersion; /**< the version of MQTT being used */ + int sessionPresent; /**< the session present flag returned from the server */ + } connect; + /** For unsubscribeMany, the list of reasonCodes returned by the server. */ + struct + { + int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */ + enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */ + } unsub; + } alt; +} MQTTAsync_successData5; + +#define MQTTAsync_successData5_initializer {{'M', 'Q', 'S', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer} + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onSuccess. + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the successful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Any success data associated with the API completion. + */ +typedef void MQTTAsync_onSuccess5(void* context, MQTTAsync_successData5* response); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure(void* context, MQTTAsync_failureData* response); + +/** + * This is a callback function, the MQTT V5 version of ::MQTTAsync_onFailure. + * The application must provide an implementation of this function to enable asynchronous + * notification of the unsuccessful completion of an API call. The function is + * registered with the client library by passing it as an argument in + * ::MQTTAsync_responseOptions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to the context value originally passed to + * ::MQTTAsync_responseOptions, which contains any application-specific context. + * @param response Failure data associated with the API completion. + */ +typedef void MQTTAsync_onFailure5(void* context, MQTTAsync_failureData5* response); + +/** Structure to define call options. For MQTT 5.0 there is input data as well as that + * describing the response method. So there is now also a synonym ::MQTTAsync_callOptions + * to better reflect the use. This responseOptions name is kept for backward + * compatibility. + */ +typedef struct MQTTAsync_responseOptions +{ + /** The eyecatcher for this structure. Must be MQTR */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * if 0, no MQTTV5 options */ + int struct_version; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the API call fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * A token is returned from the call. It can be used to track + * the state of this request, both in the callbacks and in future calls + * such as ::MQTTAsync_waitForCompletion. + */ + MQTTAsync_token token; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the API call successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /* + * MQTT V5 subscribe options, when used with subscribe only. + */ + MQTTSubscribe_options subscribeOptions; + /* + * MQTT V5 subscribe option count, when used with subscribeMany only. + * The number of entries in the subscribe_options_list array. + */ + int subscribeOptionsCount; + /* + * MQTT V5 subscribe option array, when used with subscribeMany only. + */ + MQTTSubscribe_options* subscribeOptionsList; +} MQTTAsync_responseOptions; + +#define MQTTAsync_responseOptions_initializer { {'M', 'Q', 'T', 'R'}, 1, NULL, NULL, 0, 0, NULL, NULL, MQTTProperties_initializer, MQTTSubscribe_options_initializer, 0, NULL} + +/** A synonym for responseOptions to better reflect its usage since MQTT 5.0 */ +typedef struct MQTTAsync_responseOptions MQTTAsync_callOptions; +#define MQTTAsync_callOptions_initializer MQTTAsync_responseOptions_initializer + +/** + * This function sets the global callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. If this callback is not set, an error will be returned. + * You must set this callback because otherwise there would be + * no way to deliver any incoming messages. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl, + MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc); + +/** + * This function sets the callback function for a connection lost event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed the callback functions to provide + * access to the context information in the callback. + * @param cl A pointer to an MQTTAsync_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ + +LIBMQTT_API int MQTTAsync_setConnectionLostCallback(MQTTAsync handle, void* context, + MQTTAsync_connectionLost* cl); + +/** + * This function sets the callback function for a message arrived event for + * a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. If you do not set a messageArrived callback + * function, you will not be notified of the receipt of any messages as a + * result of a subscription. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param ma A pointer to an MQTTAsync_messageArrived() callback + * function. You can set this to NULL if your application doesn't handle + * receipt of messages. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setMessageArrivedCallback(MQTTAsync handle, void* context, + MQTTAsync_messageArrived* ma); + +/** + * This function sets the callback function for a delivery complete event + * for a specific client. Any necessary message acknowledgements and status + * communications are handled in the background without any intervention + * from the client application. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to the callback functions to provide + * access to the context information in the callback. + * @param dc A pointer to an MQTTAsync_deliveryComplete() callback + * function. You can set this to NULL if you do not want to check + * for successful delivery. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setDeliveryCompleteCallback(MQTTAsync handle, void* context, + MQTTAsync_deliveryComplete* dc); + +/** + * Sets the MQTTAsync_connected() callback function for a client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTAsync_connected() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co); + + +/** + * Reconnects a client with the previously used connect options. Connect + * must have previously been called for this to work. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_reconnect(MQTTAsync handle); + + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTAsync_persistence). See also MQTTAsync_destroy(). + * @param handle A pointer to an ::MQTTAsync handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of + * the library is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTASYNC_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTAsync_create(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTAsync_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2 or 3 + * 0 means no MQTTVersion + * 1 means no allowDisconnectedSendAtAnyTime, deleteOldestMessages, restoreMessages + * 2 means no persistQoS0 + */ + int struct_version; + /** Whether to allow messages to be sent when the client library is not connected. */ + int sendWhileDisconnected; + /** The maximum number of messages allowed to be buffered while not connected. */ + int maxBufferedMessages; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; + /** + * Allow sending of messages while disconnected before a first successful connect. + */ + int allowDisconnectedSendAtAnyTime; + /* + * When the maximum number of buffered messages is reached, delete the oldest rather than the newest. + */ + int deleteOldestMessages; + /* + * Restore messages from persistence on create - or clear it. + */ + int restoreMessages; + /* + * Persist QoS0 publish commands - an option to not persist them. + */ + int persistQoS0; +} MQTTAsync_createOptions; + +#define MQTTAsync_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_DEFAULT, 0, 0, 1, 1} + +#define MQTTAsync_createOptions_initializer5 { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_5, 0, 0, 1, 1} + + +LIBMQTT_API int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTAsync_createOptions* options); + +/** + * MQTTAsync_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTAsync_willOptions + * structure is passed in the MQTTAsync_connectOptions structure used in the + * MQTTAsync_connect() call that connects the client to the server. The pointer + * to MQTTAsync_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 indicates no binary will message support + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTAsync_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTAsync_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTAsync_willOptions; + +#define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTAsync_SSLOptions; + +#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** Utility structure where name/value pairs are needed */ +typedef struct +{ + const char* name; /**< name string */ + const char* value; /**< value string */ +} MQTTAsync_nameValue; + +/** + * MQTTAsync_connectOptions defines several settings that control the way the + * client connects to an MQTT server. Default values are set in + * MQTTAsync_connectOptions_initializer. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3 4 5 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no automatic reconnect options + * 4 signifies no binary password option (just string) + * 5 signifies no MQTTV5 properties + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + * Set to 0 if you do not want any keep alive processing. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTAsync_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This controls how many messages can be in-flight simultaneously. + */ + int maxInflight; + /** + * This is a pointer to an MQTTAsync_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTAsync_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTAsync_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTAsync_SSLOptions* ssl; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * The number of entries in the serverURIs array. + */ + int serverURIcount; + /** + * An array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a domain name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + */ + int MQTTVersion; + /** + * Reconnect automatically in the case of a connection being lost? + */ + int automaticReconnect; + /** + * Minimum retry interval in seconds. Doubled on each failed retry. + */ + int minRetryInterval; + /** + * Maximum retry interval in seconds. The doubling stops here on failed retries. + */ + int maxRetryInterval; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * MQTT V5 properties for connect + */ + MQTTProperties *connectProperties; + /** + * MQTT V5 properties for the will message in the connect + */ + MQTTProperties *willProperties; + /** + * A pointer to a callback function to be called if the connect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the connect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; + /** + * HTTP headers for websockets + */ + const MQTTAsync_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTAsync_connectOptions; + + +#define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + +#define MQTTAsync_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 65535, NULL, NULL, NULL, 30, 0,\ +NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL} + + +/** + * This function attempts to connect a previously-created client (see + * MQTTAsync_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTAsync_setCallbacks() prior to MQTTAsync_connect(). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options A pointer to a valid MQTTAsync_connectOptions + * structure. + * @return ::MQTTASYNC_SUCCESS if the client connect request was accepted. + * If the client was unable to connect to the server, an error code is + * returned via the onFailure callback, if set. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options); + +/** Options for the ::MQTTAsync_disconnect call */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTD. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1. 0 signifies no V5 properties */ + int struct_version; + /** + * The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + */ + int timeout; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess* onSuccess; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure* onFailure; + /** + * A pointer to any application-specific context. The + * the context pointer is passed to success or failure callback functions to + * provide access to the context information in the callback. + */ + void* context; + /** + * MQTT V5 input properties + */ + MQTTProperties properties; + /** + * Reason code for MQTTV5 disconnect + */ + enum MQTTReasonCodes reasonCode; + /** + * A pointer to a callback function to be called if the disconnect successfully + * completes. Can be set to NULL, in which case no indication of successful + * completion will be received. + */ + MQTTAsync_onSuccess5* onSuccess5; + /** + * A pointer to a callback function to be called if the disconnect fails. + * Can be set to NULL, in which case no indication of unsuccessful + * completion will be received. + */ + MQTTAsync_onFailure5* onFailure5; +} MQTTAsync_disconnectOptions; + +#define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 0, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +#define MQTTAsync_disconnectOptions_initializer5 { {'M', 'Q', 'T', 'D'}, 1, 0, NULL, NULL, NULL,\ + MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL } + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTAsync_connectOptions.cleansession and MQTTAsync_connect()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param options The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions* options); + + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTAsync_isConnected(MQTTAsync handle); + + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTAsync_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTAsync_subscribe(MQTTAsync handle, const char* topic, int qos, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTAsync_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char* const* topic, const int* qos, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTAsync_unsubscribe(MQTTAsync handle, const char* topic, MQTTAsync_responseOptions* response); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param response A pointer to a response options structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const* topic, MQTTAsync_responseOptions* response); + + +/** + * This function attempts to publish a message to a given topic (see also + * ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * This is optional and can be set to NULL. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_send(MQTTAsync handle, const char* destinationName, int payloadlen, const void* payload, int qos, + int retained, MQTTAsync_responseOptions* response); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTAsync_publish()). An ::MQTTAsync_token is issued when + * this function returns successfully if the QoS is greater than 0. + * If the client application needs to + * test for successful delivery of messages, a callback should be set + * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param destinationName The topic associated with this message. + * @param msg A pointer to a valid MQTTAsync_message structure containing + * the payload and attributes of the message to be published. + * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions. + * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTAsync_sendMessage(MQTTAsync handle, const char* destinationName, const MQTTAsync_message* msg, MQTTAsync_responseOptions* response); + + +/** + * This function sets a pointer to an array of tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param tokens The address of a pointer to an ::MQTTAsync_token. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTASYNC_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens); + +/** + * Tests whether a request corresponding to a token is complete. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @return 1 if the request has been completed, 0 if not. + */ +#define MQTTASYNC_TRUE 1 +LIBMQTT_API int MQTTAsync_isComplete(MQTTAsync handle, MQTTAsync_token token); + + +/** + * Waits for a request corresponding to a token to complete. This only works for + * messages with QoS greater than 0. A QoS 0 message has no MQTT token. + * This function will always return ::MQTTASYNC_SUCCESS for a QoS 0 message. + * + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param token An ::MQTTAsync_token associated with a request. + * @param timeout the maximum time to wait for completion, in milliseconds + * @return ::MQTTASYNC_SUCCESS if the request has been completed in the time allocated, + * ::MQTTASYNC_FAILURE or ::MQTTASYNC_DISCONNECTED if not. + */ +LIBMQTT_API int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token token, unsigned long timeout); + + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTAsync_free() library function. + * @param msg The address of a pointer to the ::MQTTAsync_message structure + * to be freed. + */ +LIBMQTT_API void MQTTAsync_freeMessage(MQTTAsync_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTAsync_free(void* ptr); + +/** + * This function is used to allocate memory to be used or freed by the MQTT C client library, + * especially the data in the ::MQTTPersistence_afterRead and ::MQTTPersistence_beforeWrite + * callbacks. This is needed on Windows when the client library and application + * program have been compiled with different versions of the C compiler. + * @param size The size of the memory to be allocated. + */ +LIBMQTT_API void* MQTTAsync_malloc(size_t size); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTAsync_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTAsync + * structure to be freed. + */ +LIBMQTT_API void MQTTAsync_destroy(MQTTAsync* handle); + + + +enum MQTTASYNC_TRACE_LEVELS +{ + MQTTASYNC_TRACE_MAXIMUM = 1, + MQTTASYNC_TRACE_MEDIUM, + MQTTASYNC_TRACE_MINIMUM, + MQTTASYNC_TRACE_PROTOCOL, + MQTTASYNC_TRACE_ERROR, + MQTTASYNC_TRACE_SEVERE, + MQTTASYNC_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTAsync_setTraceLevel(enum MQTTASYNC_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTAsync_traceCallback(enum MQTTASYNC_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTAsync_setTraceCallback(MQTTAsync_traceCallback* callback); + +/** + * This function returns version information about the library. + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void); + +/** + * Returns a pointer to a string representation of the error code, or NULL. + * Do not free after use. Returns NULL if the error code is unknown. + * @param code the MQTTASYNC_ return code. + * @return a static string representation of the error code. + */ +LIBMQTT_API const char* MQTTAsync_strerror(int code); + + +/*! + * @cond MQTTAsync_main + * @page async Threading + * The client application runs on several threads. + * Processing of handshaking and maintaining + * the network connection is performed in the background. + * This API is thread safe: functions may be called by multiple application + * threads. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(), + * MQTTAsync_connectionLost() and MQTTAsync_deliveryComplete()). + * In addition, some functions allow success and failure callbacks to be set + * for individual requests, in the ::MQTTAsync_responseOptions structure. Applications + * can be written as a chain of callback functions. + * + * @page callbacks Callbacks + * Any function from this API may be used within a callback. It is not advisable to + * use ::MQTTAsync_waitForCompletion within a callback, however, as it is the only + * API call that may take some time to complete, which may cause unpredictable + * behaviour. All the other API calls are intended to complete quickly, starting + * a request in the background, with success or failure notified by other callbacks. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * A log message will be written to highlight the issue, but it is up + * to the application to protect against this situation. + * + * @page auto_reconnect Automatic Reconnect + * The ability for the client library to reconnect automatically in the event + * of a connection failure was added in 1.1. The connection lost callback + * allows a flexible response to the loss of a connection, so almost any + * behaviour can be implemented in that way. Automatic reconnect does have the + * advantage of being a little simpler to use. + * + * To switch on automatic reconnect, the connect options field + * automaticReconnect should be set to non-zero. The minimum and maximum times + * before the next connection attempt can also be set, the defaults being 1 and + * 60 seconds. At each failure to reconnect, the retry interval is doubled until + * the maximum value is reached, and there it stays until the connection is + * successfully re-established whereupon it is reset. + * + * When a reconnection attempt is successful, the ::MQTTAsync_connected callback + * function is invoked, if set by calling ::MQTTAsync_setConnected. This allows + * the application to take any actions needed, such as amending subscriptions. + * + * @page offline_publish Publish While Disconnected + * This feature was not originally available because with persistence enabled, + * messages could be stored locally without ever knowing if they could be sent. + * The client application could have created the client with an erroneous broker + * address or port for instance. + * + * To enable messages to be published when the application is disconnected + * ::MQTTAsync_createWithOptions must be used instead of ::MQTTAsync_create to + * create the client object. The ::MQTTAsync_createOptions field sendWhileDisconnected + * must be set to non-zero, and the maxBufferedMessages field set as required - + * the default being 100. + * + * ::MQTTAsync_getPendingTokens can be called to return the ids of the messages + * waiting to be sent, or for which the sending process has not completed. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTAsync_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page publish Publication example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed\n"); + finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + finished = 1; +} + +void onSendFailure(void* context, MQTTAsync_failureData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message send failed token %d error code %d\n", response->token, response->code); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +void onSend(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; + int rc; + + printf("Message with token value %d delivery confirmed\n", response->token); + opts.onSuccess = onDisconnect; + opts.onFailure = onDisconnectFailure; + opts.context = client; + if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response ? response->code : 0); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + MQTTAsync_message pubmsg = MQTTAsync_message_initializer; + int rc; + + printf("Successful connection\n"); + opts.onSuccess = onSend; + opts.onFailure = onSendFailure; + opts.context = client; + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start sendMessage, return code %d\n", rc); + exit(EXIT_FAILURE); + } +} + +int messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* m) +{ + // not expecting any messages + return 1; +} + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to create client object, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + if ((rc = MQTTAsync_setCallbacks(client, NULL, connlost, messageArrived, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callback, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (!finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + MQTTAsync_destroy(&client); + return rc; +} + + * @endcode + * @page subscribe Subscription example +@code +#include +#include +#include +#include "MQTTAsync.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#if defined(_WRS_KERNEL) +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int disc_finished = 0; +int subscribed = 0; +int finished = 0; + +void connlost(void *context, char *cause) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + int rc; + + printf("\nConnection lost\n"); + if (cause) + printf(" cause: %s\n", cause); + + printf("Reconnecting\n"); + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + finished = 1; + } +} + + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTAsync_freeMessage(&message); + MQTTAsync_free(topicName); + return 1; +} + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Disconnect failed, rc %d\n", response->code); + disc_finished = 1; +} + +void onDisconnect(void* context, MQTTAsync_successData* response) +{ + printf("Successful disconnection\n"); + disc_finished = 1; +} + +void onSubscribe(void* context, MQTTAsync_successData* response) +{ + printf("Subscribe succeeded\n"); + subscribed = 1; +} + +void onSubscribeFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Subscribe failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnectFailure(void* context, MQTTAsync_failureData* response) +{ + printf("Connect failed, rc %d\n", response->code); + finished = 1; +} + + +void onConnect(void* context, MQTTAsync_successData* response) +{ + MQTTAsync client = (MQTTAsync)context; + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + int rc; + + printf("Successful connection\n"); + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + opts.onSuccess = onSubscribe; + opts.onFailure = onSubscribeFailure; + opts.context = client; + if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start subscribe, return code %d\n", rc); + finished = 1; + } +} + + +int main(int argc, char* argv[]) +{ + MQTTAsync client; + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer; + int rc; + int ch; + + if ((rc = MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) + != MQTTASYNC_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTAsync_setCallbacks(client, client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + conn_opts.onSuccess = onConnect; + conn_opts.onFailure = onConnectFailure; + conn_opts.context = client; + if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + while (!subscribed && !finished) + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + + if (finished) + goto exit; + + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + disc_opts.onSuccess = onDisconnect; + disc_opts.onFailure = onDisconnectFailure; + if ((rc = MQTTAsync_disconnect(client, &disc_opts)) != MQTTASYNC_SUCCESS) + { + printf("Failed to start disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + while (!disc_finished) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + +destroy_exit: + MQTTAsync_destroy(&client); +exit: + return rc; +} + + * @endcode +* @page tracing Tracing + * + * Runtime tracing can be controlled by environment variables or API calls. + * + * #### Environment variables + * + * Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable. + * A value of ON, or stdout, prints to stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * #### Trace API calls + * + * MQTTAsync_traceCallback() is used to set a callback function which is called whenever trace + * information is available. This will be the same information as that printed if the + * environment variables were used to control the trace. + * + * The MQTTAsync_setTraceLevel() calls is used to set the maximum level of trace entries that will be + * passed to the callback function. The levels are: + * 1. ::MQTTASYNC_TRACE_MAXIMUM + * 2. ::MQTTASYNC_TRACE_MEDIUM + * 3. ::MQTTASYNC_TRACE_MINIMUM + * 4. ::MQTTASYNC_TRACE_PROTOCOL + * 5. ::MQTTASYNC_TRACE_ERROR + * 6. ::MQTTASYNC_TRACE_SEVERE + * 7. ::MQTTASYNC_TRACE_FATAL + * + * Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned. + * Choosing ::MQTTASYNC_TRACE_ERROR will cause ERROR, SEVERE and FATAL trace entries to be returned + * to the callback function. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ + +#if defined(__cplusplus) + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTAsyncUtils.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTAsyncUtils.h new file mode 100644 index 0000000..42a3145 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTAsyncUtils.h @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + +#if !defined(MQTTASYNCUTILS_H_) +#define MQTTASYNCUTILS_H_ + +#include "MQTTPacket.h" +#include "Thread.h" + +#define URI_TCP "tcp://" +#define URI_WS "ws://" +#define URI_WSS "wss://" + +enum MQTTAsync_threadStates +{ + STOPPED, STARTING, RUNNING, STOPPING +}; + +typedef struct +{ + MQTTAsync_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} qEntry; + +typedef struct +{ + int type; + MQTTAsync_onSuccess* onSuccess; + MQTTAsync_onFailure* onFailure; + MQTTAsync_onSuccess5* onSuccess5; + MQTTAsync_onFailure5* onFailure5; + MQTTAsync_token token; + void* context; + START_TIME_TYPE start_time; + MQTTProperties properties; + union + { + struct + { + int count; + char** topics; + int* qoss; + MQTTSubscribe_options opts; + MQTTSubscribe_options* optlist; + } sub; + struct + { + int count; + char** topics; + } unsub; + struct + { + char* destinationName; + int payloadlen; + void* payload; + int qos; + int retained; + } pub; + struct + { + int internal; + int timeout; + enum MQTTReasonCodes reasonCode; + } dis; + struct + { + int currentURI; + int MQTTVersion; /**< current MQTT version being used to connect */ + } conn; + } details; +} MQTTAsync_command; + +typedef struct MQTTAsync_struct +{ + char* serverURI; + int ssl; + int websocket; + Clients* c; + + /* "Global", to the client, callback definitions */ + MQTTAsync_connectionLost* cl; + MQTTAsync_messageArrived* ma; + MQTTAsync_deliveryComplete* dc; + void* clContext; /* the context to be associated with the conn lost callback*/ + void* maContext; /* the context to be associated with the msg arrived callback*/ + void* dcContext; /* the context to be associated with the deliv complete callback*/ + + MQTTAsync_connected* connected; + void* connected_context; /* the context to be associated with the connected callback*/ + + MQTTAsync_disconnected* disconnected; + void* disconnected_context; /* the context to be associated with the disconnected callback*/ + + MQTTAsync_updateConnectOptions* updateConnectOptions; + void* updateConnectOptions_context; + + /* Each time connect is called, we store the options that were used. These are reused in + any call to reconnect, or an automatic reconnect attempt */ + MQTTAsync_command connect; /* Connect operation properties */ + MQTTAsync_command disconnect; /* Disconnect operation properties */ + MQTTAsync_command* pending_write; /* Is there a socket write pending? */ + + List* responses; + unsigned int command_seqno; + + MQTTPacket* pack; + + /* added for offline buffering */ + MQTTAsync_createOptions* createOptions; + int shouldBeConnected; + int noBufferedMessages; /* the current number of buffered (publish) messages for this client */ + + /* added for automatic reconnect */ + int automaticReconnect; + int minRetryInterval; + int maxRetryInterval; + int serverURIcount; + char** serverURIs; + int connectTimeout; + + int currentInterval; + int currentIntervalBase; + START_TIME_TYPE lastConnectionFailedTime; + int retrying; + int reconnectNow; + + /* MQTT V5 properties */ + MQTTProperties* connectProps; + MQTTProperties* willProps; + +} MQTTAsyncs; + +typedef struct +{ + MQTTAsync_command command; + MQTTAsyncs* client; + unsigned int seqno; /* only used on restore */ + int not_restored; + char* key; /* if not_restored, this holds the key */ +} MQTTAsync_queuedCommand; + +void MQTTAsync_lock_mutex(mutex_type amutex); +void MQTTAsync_unlock_mutex(mutex_type amutex); +void MQTTAsync_terminate(void); +#if !defined(NO_PERSISTENCE) +int MQTTAsync_restoreCommands(MQTTAsyncs* client); +#endif +int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size); +void MQTTAsync_emptyMessageQueue(Clients* client); +void MQTTAsync_freeResponses(MQTTAsyncs* m); +void MQTTAsync_freeCommands(MQTTAsyncs* m); +int MQTTAsync_unpersistCommandsAndMessages(Clients* c); +void MQTTAsync_closeSession(Clients* client, enum MQTTReasonCodes reasonCode, MQTTProperties* props); +int MQTTAsync_disconnect1(MQTTAsync handle, const MQTTAsync_disconnectOptions* options, int internal); +int MQTTAsync_assignMsgId(MQTTAsyncs* m); +int MQTTAsync_getNoBufferedMessages(MQTTAsyncs* m); +void MQTTAsync_writeComplete(int socket, int rc); +void setRetryLoopInterval(int keepalive); + +#if defined(_WIN32) || defined(_WIN64) +#else +#define WINAPI +#endif + +thread_return_type WINAPI MQTTAsync_sendThread(void* n); +thread_return_type WINAPI MQTTAsync_receiveThread(void* n); + +#endif /* MQTTASYNCUTILS_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTClient.h new file mode 100644 index 0000000..da61357 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTClient.h @@ -0,0 +1,1945 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - multiple server connection support + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - remove const from eyecatchers #168 + *******************************************************************************/ + +/** + * @cond MQTTClient_internal + * @mainpage MQTT Client Library Internals + * In the beginning there was one MQTT C client library, MQTTClient, as implemented in MQTTClient.c + * This library was designed to be easy to use for applications which didn't mind if some of the calls + * blocked for a while. For instance, the MQTTClient_connect call will block until a successful + * connection has completed, or a connection has failed, which could be as long as the "connection + * timeout" interval, whose default is 30 seconds. + * + * However in mobile devices and other windowing environments, blocking on the GUI thread is a bad + * thing as it causes the user interface to freeze. Hence a new API, MQTTAsync, implemented + * in MQTTAsync.c, was devised. There are no blocking calls in this library, so it is well suited + * to GUI and mobile environments, at the expense of some extra complexity. + * + * Both libraries are designed to be sparing in the use of threads. So multiple client objects are + * handled by one or two threads, with a select call in Socket_getReadySocket(), used to determine + * when a socket has incoming data. This API is thread safe: functions may be called by multiple application + * threads, with the exception of ::MQTTClient_yield and ::MQTTClient_receive, which are intended + * for single threaded environments only. + * + * @endcond + * @cond MQTTClient_main + * @mainpage MQTT Client library for C + * © Copyright IBM Corp. 2009, 2020 and others + * + * @brief An MQTT client library in C. + * + * These pages describe the original more synchronous API which might be + * considered easier to use. Some of the calls will block. For the new + * totally asynchronous API where no calls block, which is especially suitable + * for use in windowed environments, see the + * MQTT C Client Asynchronous API Documentation. + * The MQTTClient API is not thread safe, whereas the MQTTAsync API is. + * + * An MQTT client application connects to MQTT-capable servers. + * A typical client is responsible for collecting information from a telemetry + * device and publishing the information to the server. It can also subscribe + * to topics, receive messages, and use this information to control the + * telemetry device. + * + * MQTT clients implement the published MQTT v3 protocol. You can write your own + * API to the MQTT protocol using the programming language and platform of your + * choice. This can be time-consuming and error-prone. + * + * To simplify writing MQTT client applications, this library encapsulates + * the MQTT v3 protocol for you. Using this library enables a fully functional + * MQTT client application to be written in a few lines of code. + * The information presented here documents the API provided + * by the MQTT Client library for C. + * + * Using the client
+ * Applications that use the client library typically use a similar structure: + *
    + *
  • Create a client object
  • + *
  • Set the options to connect to an MQTT server
  • + *
  • Set up callback functions if multi-threaded (asynchronous mode) + * operation is being used (see @ref async).
  • + *
  • Subscribe to any topics the client needs to receive
  • + *
  • Repeat until finished:
  • + *
      + *
    • Publish any messages the client needs to
    • + *
    • Handle any incoming messages
    • + *
    + *
  • Disconnect the client
  • + *
  • Free any memory being used by the client
  • + *
+ * Some simple examples are shown here: + *
    + *
  • @ref pubsync
  • + *
  • @ref pubasync
  • + *
  • @ref subasync
  • + *
+ * Additional information about important concepts is provided here: + *
    + *
  • @ref async
  • + *
  • @ref callbacks
  • + *
  • @ref wildcard
  • + *
  • @ref qos
  • + *
  • @ref tracing
  • + *
+ * @endcond + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENT_H) +#define MQTTCLIENT_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include +/* +/// @endcond +*/ + +#include "MQTTExportDeclarations.h" + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" +#include "MQTTSubscribeOpts.h" +#if !defined(NO_PERSISTENCE) +#include "MQTTClientPersistence.h" +#endif + +/** + * Return code: No error. Indicates successful completion of an MQTT client + * operation. + */ +#define MQTTCLIENT_SUCCESS 0 +/** + * Return code: A generic error code indicating the failure of an MQTT client + * operation. + */ +#define MQTTCLIENT_FAILURE -1 + +/* error code -2 is MQTTCLIENT_PERSISTENCE_ERROR */ + +/** + * Return code: The client is disconnected. + */ +#define MQTTCLIENT_DISCONNECTED -3 +/** + * Return code: The maximum number of messages allowed to be simultaneously + * in-flight has been reached. + */ +#define MQTTCLIENT_MAX_MESSAGES_INFLIGHT -4 +/** + * Return code: An invalid UTF-8 string has been detected. + */ +#define MQTTCLIENT_BAD_UTF8_STRING -5 +/** + * Return code: A NULL parameter has been supplied when this is invalid. + */ +#define MQTTCLIENT_NULL_PARAMETER -6 +/** + * Return code: The topic has been truncated (the topic string includes + * embedded NULL characters). String functions will not access the full topic. + * Use the topic length value to access the full topic. + */ +#define MQTTCLIENT_TOPICNAME_TRUNCATED -7 +/** + * Return code: A structure parameter does not have the correct eyecatcher + * and version number. + */ +#define MQTTCLIENT_BAD_STRUCTURE -8 +/** + * Return code: A QoS value that falls outside of the acceptable range (0,1,2) + */ +#define MQTTCLIENT_BAD_QOS -9 +/** + * Return code: Attempting SSL connection using non-SSL version of library + */ +#define MQTTCLIENT_SSL_NOT_SUPPORTED -10 + /** + * Return code: unrecognized MQTT version + */ + #define MQTTCLIENT_BAD_MQTT_VERSION -11 +/** + * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss:// + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + */ +#define MQTTCLIENT_BAD_PROTOCOL -14 + /** + * Return code: option not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_BAD_MQTT_OPTION -15 + /** + * Return code: call not applicable to the requested version of MQTT + */ + #define MQTTCLIENT_WRONG_MQTT_VERSION -16 + /** + * Return code: 0 length will topic on connect + */ + #define MQTTCLIENT_0_LEN_WILL_TOPIC -17 + + +/** + * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1 + */ +#define MQTTVERSION_DEFAULT 0 +/** + * MQTT version to connect with: 3.1 + */ +#define MQTTVERSION_3_1 3 +/** + * MQTT version to connect with: 3.1.1 + */ +#define MQTTVERSION_3_1_1 4 + /** + * MQTT version to connect with: 5 + */ + #define MQTTVERSION_5 5 +/** + * Bad return code from subscribe, as defined in the 3.1.1 specification + */ +#define MQTT_BAD_SUBSCRIBE 0x80 + +/** + * Initialization options + */ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTG. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** 1 = we do openssl init, 0 = leave it to the application */ + int do_openssl_init; +} MQTTClient_init_options; + +#define MQTTClient_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 } + +/** + * Global init of mqtt library. Call once on program start to set global behaviour. + * do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library (0) + */ +LIBMQTT_API void MQTTClient_global_init(MQTTClient_init_options* inits); + +/** + * A handle representing an MQTT client. A valid client handle is available + * following a successful call to MQTTClient_create(). + */ +typedef void* MQTTClient; +/** + * A value representing an MQTT message. A delivery token is returned to the + * client application when a message is published. The token can then be used to + * check that the message was successfully delivered to its destination (see + * MQTTClient_publish(), + * MQTTClient_publishMessage(), + * MQTTClient_deliveryComplete(), + * MQTTClient_waitForCompletion() and + * MQTTClient_getPendingDeliveryTokens()). + */ +typedef int MQTTClient_deliveryToken; +typedef int MQTTClient_token; + +/** + * A structure representing the payload and attributes of an MQTT message. The + * message topic is not part of this structure (see MQTTClient_publishMessage(), + * MQTTClient_publish(), MQTTClient_receive(), MQTTClient_freeMessage() + * and MQTTClient_messageArrived()). + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTM. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + * 0 indicates no message properties */ + int struct_version; + /** The length of the MQTT message payload in bytes. */ + int payloadlen; + /** A pointer to the payload of the MQTT message. */ + void* payload; + /** + * The quality of service (QoS) assigned to the message. + * There are three levels of QoS: + *
+ *
QoS0
+ *
Fire and forget - the message may not be delivered
+ *
QoS1
+ *
At least once - the message will be delivered, but may be + * delivered more than once in some circumstances.
+ *
QoS2
+ *
Once and one only - the message will be delivered exactly once.
+ *
+ */ + int qos; + /** + * The retained flag serves two purposes depending on whether the message + * it is associated with is being published or received. + * + * retained = true
+ * For messages being published, a true setting indicates that the MQTT + * server should retain a copy of the message. The message will then be + * transmitted to new subscribers to a topic that matches the message topic. + * For subscribers registering a new subscription, the flag being true + * indicates that the received message is not a new one, but one that has + * been retained by the MQTT server. + * + * retained = false
+ * For publishers, this indicates that this message should not be retained + * by the MQTT server. For subscribers, a false setting indicates this is + * a normal message, received as a result of it being published to the + * server. + */ + int retained; + /** + * The dup flag indicates whether or not this message is a duplicate. + * It is only meaningful when receiving QoS1 messages. When true, the + * client application should take appropriate action to deal with the + * duplicate message. + */ + int dup; + /** The message identifier is normally reserved for internal use by the + * MQTT client and server. + */ + int msgid; + /** + * The MQTT V5 properties associated with the message. + */ + MQTTProperties properties; +} MQTTClient_message; + +#define MQTTClient_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer } + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * receipt of messages. The function is registered with the client library by + * passing it as an argument to MQTTClient_setCallbacks(). It is + * called by the client library when a new message that matches a client + * subscription has been received from the server. This function is executed on + * a separate thread to the one on which the client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param topicName The topic associated with the received message. + * @param topicLen The length of the topic if there are one + * more NULL characters embedded in topicName, otherwise topicLen + * is 0. If topicLen is 0, the value returned by strlen(topicName) + * can be trusted. If topicLen is greater than 0, the full topic name + * can be retrieved by accessing topicName as a byte array of length + * topicLen. + * @param message The MQTTClient_message structure for the received message. + * This structure contains the message payload and attributes. + * @return This function must return 0 or 1 indicating whether or not + * the message has been safely received by the client application.
+ * Returning 1 indicates that the message has been successfully handled. + * To free the message storage, ::MQTTClient_freeMessage must be called. + * To free the topic name storage, ::MQTTClient_free must be called.
+ * Returning 0 indicates that there was a problem. In this + * case, the client library will reinvoke MQTTClient_messageArrived() to + * attempt to deliver the message to the application again. + * Do not free the message and topic storage when returning 0, otherwise + * the redelivery will fail. + */ +typedef int MQTTClient_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* message); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of delivery of messages. The function is registered with the + * client library by passing it as an argument to MQTTClient_setCallbacks(). + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note:MQTTClient_deliveryComplete() is not called when messages are + * published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + */ +typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken dt); + +/** + * This is a callback function. The client application + * must provide an implementation of this function to enable asynchronous + * notification of the loss of connection to the server. The function is + * registered with the client library by passing it as an argument to + * MQTTClient_setCallbacks(). It is called by the client library if the client + * loses its connection to the server. The client application must take + * appropriate action, such as trying to reconnect or reporting the problem. + * This function is executed on a separate thread to the one on which the + * client application is running. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param cause The reason for the disconnection. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_connectionLost(void* context, char* cause); + +/** + * This function sets the callback functions for a specific client. + * If your client application doesn't use a particular callback, set the + * relevant parameter to NULL. Calling MQTTClient_setCallbacks() puts the + * client into multi-threaded mode. Any necessary message acknowledgements and + * status communications are handled in the background without any intervention + * from the client application. See @ref async for more information. + * + * Note: The MQTT client must be disconnected when this function is + * called. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param cl A pointer to an MQTTClient_connectionLost() callback + * function. You can set this to NULL if your application doesn't handle + * disconnections. + * @param ma A pointer to an MQTTClient_messageArrived() callback + * function. This callback function must be set when you call + * MQTTClient_setCallbacks(), as otherwise there would be nowhere to deliver + * any incoming messages. + * @param dc A pointer to an MQTTClient_deliveryComplete() callback + * function. You can set this to NULL if your application publishes + * synchronously or if you do not want to check for successful delivery. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl, + MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc); + + +/** + * This is a callback function, which will be called when the a disconnect + * packet is received from the server. This applies to MQTT V5 and above only. + * @param context A pointer to the context value originally passed to + * ::MQTTClient_setDisconnected(), which contains any application-specific context. + * @param properties The MQTT V5 properties received with the disconnect, if any. + * @param reasonCode The MQTT V5 reason code received with the disconnect. + * Currently, cause is always set to NULL. + */ +typedef void MQTTClient_disconnected(void* context, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +/** + * Sets the MQTTClient_disconnected() callback function for a client. This will be called + * if a disconnect packet is received from the server. Only valid for MQTT V5 and above. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param co A pointer to an MQTTClient_disconnected() callback + * function. NULL removes the callback setting. + * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set, + * ::MQTTCLIENT_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTClient_setDisconnected(MQTTClient handle, void* context, MQTTClient_disconnected* co); + +/** + * This is a callback function, the MQTT V5 version of MQTTClient_deliveryComplete(). + * The client application + * must provide an implementation of this function to enable asynchronous + * notification of the completed delivery of messages. + * It is called by the client library after the client application has + * published a message to the server. It indicates that the necessary + * handshaking and acknowledgements for the requested quality of service (see + * MQTTClient_message.qos) have been completed. This function is executed on a + * separate thread to the one on which the client application is running. + * Note: It is not called when messages are published at QoS0. + * @param context A pointer to the context value originally passed to + * MQTTClient_setCallbacks(), which contains any application-specific context. + * @param dt The ::MQTTClient_deliveryToken associated with + * the published message. Applications can check that all messages have been + * correctly published by matching the delivery tokens returned from calls to + * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed + * to this callback. + * @param packet_type the last received packet type for this completion. For QoS 1 + * always PUBACK. For QoS 2 could be PUBREC or PUBCOMP. + * @param properties the MQTT V5 properties returned with the last packet from the server + * @param reasonCode the reason code returned from the server + */ +typedef void MQTTClient_published(void* context, int dt, int packet_type, MQTTProperties* properties, + enum MQTTReasonCodes reasonCode); + +LIBMQTT_API int MQTTClient_setPublished(MQTTClient handle, void* context, MQTTClient_published* co); + +/** + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context); + +/** Options for the ::MQTTClient_createWithOptions call */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQCO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set. + * MQTT V5 has to be chosen here, because during the create call the message persistence + * is initialized, and we want to know whether the format of any persisted messages + * is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or + * 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */ + int MQTTVersion; +} MQTTClient_createOptions; + +#define MQTTClient_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, MQTTVERSION_DEFAULT } + +/** + * A version of :MQTTClient_create() with additional options. + * This function creates an MQTT client ready for connection to the + * specified server and using the specified persistent storage (see + * MQTTClient_persistence). See also MQTTClient_destroy(). + * @param handle A pointer to an ::MQTTClient handle. The handle is + * populated with a valid client reference following a successful return from + * this function. + * @param serverURI A null-terminated string specifying the server to + * which the client will connect. It takes the form protocol://host:port. + * Currently, protocol must be tcp or ssl. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * @param clientId The client identifier passed to the server when the + * client connects to it. It is a null-terminated UTF-8 encoded string. + * @param persistence_type The type of persistence to be used by the client: + *
+ * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or + * system on which the client is running fails or is switched off, the current + * state of any in-flight messages is lost and some messages may not be + * delivered even at QoS1 and QoS2. + *
+ * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) + * persistence mechanism. Status about in-flight messages is held in persistent + * storage and provides some protection against message loss in the case of + * unexpected failure. + *
+ * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence + * implementation. Using this type of persistence gives control of the + * persistence mechanism to the application. The application has to implement + * the MQTTClient_persistence interface. + * @param persistence_context If the application uses + * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should + * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it + * should be set to the location of the persistence directory (if set + * to NULL, the persistence directory used is the working directory). + * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this + * argument to point to a valid MQTTClient_persistence structure. + * @param options additional options for the create. + * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise + * an error code is returned. + */ +LIBMQTT_API int MQTTClient_createWithOptions(MQTTClient* handle, const char* serverURI, const char* clientId, + int persistence_type, void* persistence_context, MQTTClient_createOptions* options); + +/** + * MQTTClient_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for + * the client. In the event that a client unexpectedly loses its connection to + * the server, the server publishes the LWT message to the LWT topic on + * behalf of the client. This allows other clients (subscribed to the LWT topic) + * to be made aware that the client has disconnected. To enable the LWT + * function for a specific client, a valid pointer to an MQTTClient_willOptions + * structure is passed in the MQTTClient_connectOptions structure used in the + * MQTTClient_connect() call that connects the client to the server. The pointer + * to MQTTClient_willOptions can be set to NULL if the LWT function is not + * required. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 or 1 + 0 means there is no binary payload option + */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + const char* topicName; + /** The LWT payload in string form. */ + const char* message; + /** + * The retained flag for the LWT message (see MQTTClient_message.retained). + */ + int retained; + /** + * The quality of service setting for the LWT message (see + * MQTTClient_message.qos and @ref qos). + */ + int qos; + /** The LWT payload in binary form. This is only checked and used if the message option is NULL */ + struct + { + int len; /**< binary payload length */ + const void* data; /**< binary payload data */ + } payload; +} MQTTClient_willOptions; + +#define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} } + +#define MQTT_SSL_VERSION_DEFAULT 0 +#define MQTT_SSL_VERSION_TLS_1_0 1 +#define MQTT_SSL_VERSION_TLS_1_1 2 +#define MQTT_SSL_VERSION_TLS_1_2 3 + +/** +* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the +* OpenSSL library. It covers the following scenarios: +* - Server authentication: The client needs the digital certificate of the server. It is included +* in a store containting trusted material (also known as "trust store"). +* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In +* addition to the digital certificate of the server in a trust store, the client will need its own +* digital certificate and the private key used to sign its digital certificate stored in a "key store". +* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed +* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to +* man-in-the-middle attacks. +*/ +typedef struct +{ + /** The eyecatcher for this structure. Must be MQTS */ + char struct_id[4]; + + /** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5. + * 0 means no sslVersion + * 1 means no verify, CApath + * 2 means no ssl_error_context, ssl_error_cb + * 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore + * 4 means no protos, protos_len + */ + int struct_version; + + /** The file in PEM format containing the public digital certificates trusted by the client. */ + const char* trustStore; + + /** The file in PEM format containing the public certificate chain of the client. It may also include + * the client's private key. + */ + const char* keyStore; + + /** If not included in the sslKeyStore, this setting points to the file in PEM format containing + * the client's private key. + */ + const char* privateKey; + + /** The password to load the client's privateKey if encrypted. */ + const char* privateKeyPassword; + + /** + * The list of cipher suites that the client will present to the server during the SSL handshake. For a + * full explanation of the cipher list format, please see the OpenSSL on-line documentation: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT + * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding + * those offering no encryption- will be considered. + * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance). + */ + const char* enabledCipherSuites; + + /** True/False option to enable verification of the server certificate **/ + int enableServerCertAuth; + + /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0), + * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3). + * Only used if struct_version is >= 1. + */ + int sslVersion; + + /** + * Whether to carry out post-connect checks, including that a certificate + * matches the given host name. + * Exists only if struct_version >= 2 + */ + int verify; + + /** + * From the OpenSSL documentation: + * If CApath is not NULL, it points to a directory containing CA certificates in PEM format. + * Exists only if struct_version >= 2 + */ + const char* CApath; + + /** + * Callback function for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + int (*ssl_error_cb) (const char *str, size_t len, void *u); + + /** + * Application-specific contex for OpenSSL error handler ERR_print_errors_cb + * Exists only if struct_version >= 3 + */ + void* ssl_error_context; + + /** + * Callback function for setting TLS-PSK options. Parameters correspond to that of + * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context. + * Exists only if struct_version >= 4 + */ + unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u); + + /** + * Application-specific contex for ssl_psk_cb + * Exists only if struct_version >= 4 + */ + void* ssl_psk_context; + + /** + * Don't load default SSL CA. Should be used together with PSK to make sure + * regular servers with certificate in place is not accepted. + * Exists only if struct_version >= 4 + */ + int disableDefaultTrustStore; + + /** + * The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings. + * The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. + * A truncated byte-string is invalid. + * Check documentation for SSL_CTX_set_alpn_protos + * Exists only if struct_version >= 5 + */ + const unsigned char *protos; + + /** + * The length of the vector protos vector + * Exists only if struct_version >= 5 + */ + unsigned int protos_len; +} MQTTClient_SSLOptions; + +#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } + +/** + * MQTTClient_libraryInfo is used to store details relating to the currently used + * library such as the version in use, the time it was built and relevant openSSL + * options. + * There is one static instance of this struct in MQTTClient.c + */ + +typedef struct +{ + const char* name; + const char* value; +} MQTTClient_nameValue; + +/** + * This function returns version information about the library. + * no trace information will be returned. + * @return an array of strings describing the library. The last entry is a NULL pointer. + */ +LIBMQTT_API MQTTClient_nameValue* MQTTClient_getVersionInfo(void); + +/** + * MQTTClient_connectOptions defines several settings that control the way the + * client connects to an MQTT server. + * + * Note: Default values are not defined for members of + * MQTTClient_connectOptions so it is good practice to specify all settings. + * If the MQTTClient_connectOptions structure is defined as an automatic + * variable, all members are set to random values and thus must be set by the + * client application. If the MQTTClient_connectOptions structure is defined + * as a static variable, initialization (in compliant compilers) sets all + * values to 0 (NULL for pointers). A #keepAliveInterval setting of 0 prevents + * correct operation of the client and so you must at least set a value + * for #keepAliveInterval. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0, 1, 2, 3, 4, 5, 6, 7 or 8. + * 0 signifies no SSL options and no serverURIs + * 1 signifies no serverURIs + * 2 signifies no MQTTVersion + * 3 signifies no returned values + * 4 signifies no binary password option + * 5 signifies no maxInflightMessages and cleanstart + * 6 signifies no HTTP headers option + * 7 signifies no HTTP proxy and HTTPS proxy options + */ + int struct_version; + /** The "keep alive" interval, measured in seconds, defines the maximum time + * that should pass without communication between the client and the server + * The client will ensure that at least one message travels across the + * network within each keep alive period. In the absence of a data-related + * message during the time period, the client sends a very small MQTT + * "ping" message, which the server will acknowledge. The keep alive + * interval enables the client to detect when the server is no longer + * available without having to wait for the long TCP/IP timeout. + */ + int keepAliveInterval; + /** + * This is a boolean value. The cleansession setting controls the behaviour + * of both the client and the server at connection and disconnection time. + * The client and server both maintain session state information. This + * information is used to ensure "at least once" and "exactly once" + * delivery, and "exactly once" receipt of messages. Session state also + * includes subscriptions created by an MQTT client. You can choose to + * maintain or discard state information between sessions. + * + * When cleansession is true, the state information is discarded at + * connect and disconnect. Setting cleansession to false keeps the state + * information. When you connect an MQTT client application with + * MQTTClient_connect(), the client identifies the connection using the + * client identifier and the address of the server. The server checks + * whether session information for this client + * has been saved from a previous connection to the server. If a previous + * session still exists, and cleansession=true, then the previous session + * information at the client and server is cleared. If cleansession=false, + * the previous session is resumed. If no previous session exists, a new + * session is started. + */ + int cleansession; + /** + * This is a boolean value that controls how many messages can be in-flight + * simultaneously. Setting reliable to true means that a published + * message must be completed (acknowledgements received) before another + * can be sent. Attempts to publish additional messages receive an + * ::MQTTCLIENT_MAX_MESSAGES_INFLIGHT return code. Setting this flag to + * false allows up to 10 messages to be in-flight. This can increase + * overall throughput in some circumstances. + */ + int reliable; + /** + * This is a pointer to an MQTTClient_willOptions structure. If your + * application does not make use of the Last Will and Testament feature, + * set this pointer to NULL. + */ + MQTTClient_willOptions* will; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the user name + * parameter. + */ + const char* username; + /** + * MQTT servers that support the MQTT v3.1.1 protocol provide authentication + * and authorisation by user name and password. This is the password + * parameter. + */ + const char* password; + /** + * The time interval in seconds to allow a connect to complete. + */ + int connectTimeout; + /** + * The time interval in seconds after which unacknowledged publish requests are + * retried during a TCP session. With MQTT 3.1.1 and later, retries are + * not required except on reconnect. 0 turns off in-session retries, and is the + * recommended setting. Adding retries to an already overloaded network only + * exacerbates the problem. + */ + int retryInterval; + /** + * This is a pointer to an MQTTClient_SSLOptions structure. If your + * application does not make use of SSL, set this pointer to NULL. + */ + MQTTClient_SSLOptions* ssl; + /** + * The number of entries in the optional serverURIs array. Defaults to 0. + */ + int serverURIcount; + /** + * An optional array of null-terminated strings specifying the servers to + * which the client will connect. Each string takes the form protocol://host:port. + * protocol must be tcp, ssl, ws or wss. + * The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library + * is linked with. + * For host, you can + * specify either an IP address or a host name. For instance, to connect to + * a server running on the local machines with the default MQTT port, specify + * tcp://localhost:1883. + * If this list is empty (the default), the server URI specified on MQTTClient_create() + * is used. + */ + char* const* serverURIs; + /** + * Sets the version of MQTT to be used on the connect. + * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1 + * MQTTVERSION_3_1 (3) = only try version 3.1 + * MQTTVERSION_3_1_1 (4) = only try version 3.1.1 + * MQTTVERSION_5 (5) = only try version 5.0 + */ + int MQTTVersion; + /** + * Returned from the connect when the MQTT version used to connect is 3.1.1 + */ + struct + { + const char* serverURI; /**< the serverURI connected to */ + int MQTTVersion; /**< the MQTT version used to connect with */ + int sessionPresent; /**< if the MQTT version is 3.1.1, the value of sessionPresent returned in the connack */ + } returned; + /** + * Optional binary password. Only checked and used if the password option is NULL + */ + struct + { + int len; /**< binary password length */ + const void* data; /**< binary password data */ + } binarypwd; + /** + * The maximum number of messages in flight + */ + int maxInflightMessages; + /* + * MQTT V5 clean start flag. Only clears state at the beginning of the session. + */ + int cleanstart; + /** + * HTTP headers for websockets + */ + const MQTTClient_nameValue* httpHeaders; + /** + * HTTP proxy for websockets + */ + const char* httpProxy; + /** + * HTTPS proxy for websockets + */ + const char* httpsProxy; +} MQTTClient_connectOptions; + +#define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL, NULL} + +#define MQTTClient_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\ +0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL} + +/** + * This function attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @return ::MQTTCLIENT_SUCCESS if the client successfully connects to the + * server. An error code is returned if the client was unable to connect to + * the server. + * Error codes greater than 0 are returned by the MQTT protocol:

+ * 1: Connection refused: Unacceptable protocol version
+ * 2: Connection refused: Identifier rejected
+ * 3: Connection refused: Server unavailable
+ * 4: Connection refused: Bad user name or password
+ * 5: Connection refused: Not authorized
+ * 6-255: Reserved for future use
+ */ +LIBMQTT_API int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options); + +/** MQTT version 5.0 response information */ +typedef struct MQTTResponse +{ + int version; /* the version number of this structure */ + enum MQTTReasonCodes reasonCode; /* the MQTT 5.0 reason code returned */ + int reasonCodeCount; /* the number of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + enum MQTTReasonCodes* reasonCodes; /* a list of reason codes. Used for subscribeMany5 and unsubscribeMany5 */ + MQTTProperties* properties; /* optionally, the MQTT 5.0 properties returned */ +} MQTTResponse; + +#define MQTTResponse_initializer {1, MQTTREASONCODE_SUCCESS, 0, NULL, NULL} + +/** + * Frees the storage associated with the MQTT response. + * @param response the response structure to be freed + */ +LIBMQTT_API void MQTTResponse_free(MQTTResponse response); + +/** + * Attempts to connect a previously-created client (see + * MQTTClient_create()) to an MQTT server using MQTT version 5.0 and the specified options. If you + * want to enable asynchronous message and status notifications, you must call + * MQTTClient_setCallbacks() prior to MQTTClient_connect(). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param options A pointer to a valid MQTTClient_connectOptions + * structure. + * @param connectProperties the MQTT 5.0 connect properties to use + * @param willProperties the MQTT 5.0 properties to set on the will message + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_connect5(MQTTClient handle, MQTTClient_connectOptions* options, + MQTTProperties* connectProperties, MQTTProperties* willProperties); + +/** + * This function attempts to disconnect the client from the MQTT + * server. In order to allow the client time to complete handling of messages + * that are in-flight when this function is called, a timeout period is + * specified. When the timeout period has expired, the client disconnects even + * if there are still outstanding message acknowledgements. + * The next time the client connects to the same server, any QoS 1 or 2 + * messages which have not completed will be retried depending on the + * cleansession settings for both the previous and the new connection (see + * MQTTClient_connectOptions.cleansession and MQTTClient_connect()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param timeout The client delays disconnection for up to this time (in + * milliseconds) in order to allow in-flight message transfers to complete. + * @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from + * the server. An error code is returned if the client was unable to disconnect + * from the server + */ +LIBMQTT_API int MQTTClient_disconnect(MQTTClient handle, int timeout); + +LIBMQTT_API int MQTTClient_disconnect5(MQTTClient handle, int timeout, enum MQTTReasonCodes reason, MQTTProperties* props); + +/** + * This function allows the client application to test whether or not a + * client is currently connected to the MQTT server. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @return Boolean true if the client is connected, otherwise false. + */ +LIBMQTT_API int MQTTClient_isConnected(MQTTClient handle); + + +/* Subscribe is synchronous. QoS list parameter is changed on return to granted QoSs. + Returns return code, MQTTCLIENT_SUCCESS == success, non-zero some sort of error (TBD) */ + +/** + * This function attempts to subscribe a client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscription. + */ +LIBMQTT_API int MQTTClient_subscribe(MQTTClient handle, const char* topic, int qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a single topic, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for the subscription + * (see also MQTTClient_subscribeMany()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The subscription topic, which may include wildcards. + * @param qos The requested quality of service for the subscription. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribe5(MQTTClient handle, const char* topic, int qos, + MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to subscribe a client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful. + * An error code is returned if there was a problem registering the + * subscriptions. + */ +LIBMQTT_API int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos); + +/** + * This function attempts to subscribe an MQTT version 5.0 client to a list of topics, which may + * contain wildcards (see @ref wildcard). This call also specifies the + * @ref qos requested for each topic (see also MQTTClient_subscribe()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number of topics for which the client is requesting + * subscriptions. + * @param topic An array (of length count) of pointers to + * topics, each of which may include wildcards. + * @param qos An array (of length count) of @ref qos + * values. qos[n] is the requested QoS for topic[n]. + * @param opts the MQTT 5.0 subscribe options to be used + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_subscribeMany5(MQTTClient handle, int count, char* const* topic, + int* qos, MQTTSubscribe_options* opts, MQTTProperties* props); + +/** + * This function attempts to remove an existing subscription made by the + * specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @return ::MQTTCLIENT_SUCCESS if the subscription is removed. + * An error code is returned if there was a problem removing the + * subscription. + */ +LIBMQTT_API int MQTTClient_unsubscribe(MQTTClient handle, const char* topic); + +/** + * This function attempts to remove an existing subscription made by the + * specified client using MQTT 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topic The topic for the subscription to be removed, which may + * include wildcards (see @ref wildcard). + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribe5(MQTTClient handle, const char* topic, MQTTProperties* props); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @return ::MQTTCLIENT_SUCCESS if the subscriptions are removed. + * An error code is returned if there was a problem removing the subscriptions. + */ +LIBMQTT_API int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic); + +/** + * This function attempts to remove existing subscriptions to a list of topics + * made by the specified client using MQTT version 5.0. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param count The number subscriptions to be removed. + * @param topic An array (of length count) of pointers to the topics of + * the subscriptions to be removed, each of which may include wildcards. + * @param props the MQTT 5.0 properties to be used + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_unsubscribeMany5(MQTTClient handle, int count, char* const* topic, MQTTProperties* props); + +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publishMessage()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publish(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, int qos, int retained, + MQTTClient_deliveryToken* dt); + +/** + * Attempts to publish a message to a given topic using MQTT version 5.0 (see also + * MQTTClient_publishMessage5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param payloadlen The length of the payload in bytes. + * @param payload A pointer to the byte array payload of the message. + * @param qos The @ref qos of the message. + * @param retained The retained flag for the message. + * @param properties the MQTT 5.0 properties to be used + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publish5(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, + int qos, int retained, MQTTProperties* properties, MQTTClient_deliveryToken* dt); +/** + * This function attempts to publish a message to a given topic (see also + * MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication. + * An error code is returned if there was a problem accepting the message. + */ +LIBMQTT_API int MQTTClient_publishMessage(MQTTClient handle, const char* topicName, MQTTClient_message* msg, MQTTClient_deliveryToken* dt); + + +/** + * Attempts to publish a message to the given topic using MQTT version 5.0 + * (see also + * MQTTClient_publish5()). An ::MQTTClient_deliveryToken is issued when + * this function returns successfully. If the client application needs to + * test for succesful delivery of QoS1 and QoS2 messages, this can be done + * either asynchronously or synchronously (see @ref async, + * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The topic associated with this message. + * @param msg A pointer to a valid MQTTClient_message structure containing + * the payload and attributes of the message to be published. + * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated + * with a token representing the message when the function returns + * successfully. If your application does not use delivery tokens, set this + * argument to NULL. + * @return the MQTT 5.0 response information: error codes and properties. + */ +LIBMQTT_API MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char* topicName, MQTTClient_message* msg, + MQTTClient_deliveryToken* dt); + +/** + * This function is called by the client application to synchronize execution + * of the main thread with completed publication of a message. When called, + * MQTTClient_waitForCompletion() blocks execution until the message has been + * successful delivered or the specified timeout has expired. See @ref async. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param dt The ::MQTTClient_deliveryToken that represents the message being + * tested for successful delivery. Delivery tokens are issued by the + * publishing functions MQTTClient_publish() and MQTTClient_publishMessage(). + * @param timeout The maximum time to wait in milliseconds. + * @return ::MQTTCLIENT_SUCCESS if the message was successfully delivered. + * An error code is returned if the timeout expires or there was a problem + * checking the token. + */ +LIBMQTT_API int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken dt, unsigned long timeout); + + +/** + * This function sets a pointer to an array of delivery tokens for + * messages that are currently in-flight (pending completion). + * + * Important note: The memory used to hold the array of tokens is + * malloc()'d in this function. The client application is responsible for + * freeing this memory when it is no longer required. + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param tokens The address of a pointer to an ::MQTTClient_deliveryToken. + * When the function returns successfully, the pointer is set to point to an + * array of tokens representing messages pending completion. The last member of + * the array is set to -1 to indicate there are no more tokens. If no tokens + * are pending, the pointer is set to NULL. + * @return ::MQTTCLIENT_SUCCESS if the function returns successfully. + * An error code is returned if there was a problem obtaining the list of + * pending tokens. + */ +LIBMQTT_API int MQTTClient_getPendingDeliveryTokens(MQTTClient handle, MQTTClient_deliveryToken **tokens); + +/** + * When implementing a single-threaded client, call this function periodically + * to allow processing of message retries and to send MQTT keepalive pings. + * If the application is calling MQTTClient_receive() regularly, then it is + * not necessary to call this function. + */ +LIBMQTT_API void MQTTClient_yield(void); + +/** + * This function performs a synchronous receive of incoming messages. It should + * be used only when the client application has not set callback methods to + * support asynchronous receipt of messages (see @ref async and + * MQTTClient_setCallbacks()). Using this function allows a single-threaded + * client subscriber application to be written. When called, this function + * blocks until the next message arrives or the specified timeout expires + *(see also MQTTClient_yield()). + * + * Important note: The application must free() the memory allocated + * to the topic and the message when processing is complete (see + * MQTTClient_freeMessage()). + * @param handle A valid client handle from a successful call to + * MQTTClient_create(). + * @param topicName The address of a pointer to a topic. This function + * allocates the memory for the topic and returns it to the application + * by setting topicName to point to the topic. + * @param topicLen The length of the topic. If the return code from this + * function is ::MQTTCLIENT_TOPICNAME_TRUNCATED, the topic contains embedded + * NULL characters and the full topic should be retrieved by using + * topicLen. + * @param message The address of a pointer to the received message. This + * function allocates the memory for the message and returns it to the + * application by setting message to point to the received message. + * The pointer is set to NULL if the timeout expires. + * @param timeout The length of time to wait for a message in milliseconds. + * @return ::MQTTCLIENT_SUCCESS or ::MQTTCLIENT_TOPICNAME_TRUNCATED if a + * message is received. ::MQTTCLIENT_SUCCESS can also indicate that the + * timeout expired, in which case message is NULL. An error code is + * returned if there was a problem trying to receive a message. + */ +LIBMQTT_API int MQTTClient_receive(MQTTClient handle, char** topicName, int* topicLen, MQTTClient_message** message, + unsigned long timeout); + +/** + * This function frees memory allocated to an MQTT message, including the + * additional memory allocated to the message payload. The client application + * calls this function when the message has been fully processed. Important + * note: This function does not free the memory allocated to a message + * topic string. It is the responsibility of the client application to free + * this memory using the MQTTClient_free() library function. + * @param msg The address of a pointer to the ::MQTTClient_message structure + * to be freed. + */ +LIBMQTT_API void MQTTClient_freeMessage(MQTTClient_message** msg); + +/** + * This function frees memory allocated by the MQTT C client library, especially the + * topic name. This is needed on Windows when the client libary and application + * program have been compiled with different versions of the C compiler. It is + * thus good policy to always use this function when freeing any MQTT C client- + * allocated memory. + * @param ptr The pointer to the client library storage to be freed. + */ +LIBMQTT_API void MQTTClient_free(void* ptr); + +/** + * This function frees the memory allocated to an MQTT client (see + * MQTTClient_create()). It should be called when the client is no longer + * required. + * @param handle A pointer to the handle referring to the ::MQTTClient + * structure to be freed. + */ +LIBMQTT_API void MQTTClient_destroy(MQTTClient* handle); + + +enum MQTTCLIENT_TRACE_LEVELS +{ + MQTTCLIENT_TRACE_MAXIMUM = 1, + MQTTCLIENT_TRACE_MEDIUM, + MQTTCLIENT_TRACE_MINIMUM, + MQTTCLIENT_TRACE_PROTOCOL, + MQTTCLIENT_TRACE_ERROR, + MQTTCLIENT_TRACE_SEVERE, + MQTTCLIENT_TRACE_FATAL, +}; + + +/** + * This function sets the level of trace information which will be + * returned in the trace callback. + * @param level the trace level required + */ +LIBMQTT_API void MQTTClient_setTraceLevel(enum MQTTCLIENT_TRACE_LEVELS level); + + +/** + * This is a callback function prototype which must be implemented if you want + * to receive trace information. + * @param level the trace level of the message returned + * @param message the trace message. This is a pointer to a static buffer which + * will be overwritten on each call. You must copy the data if you want to keep + * it for later. + */ +typedef void MQTTClient_traceCallback(enum MQTTCLIENT_TRACE_LEVELS level, char* message); + +/** + * This function sets the trace callback if needed. If set to NULL, + * no trace information will be returned. The default trace level is + * MQTTASYNC_TRACE_MINIMUM. + * @param callback a pointer to the function which will handle the trace information + */ +LIBMQTT_API void MQTTClient_setTraceCallback(MQTTClient_traceCallback* callback); + +/** + * Sets the timeout value for un/subscribe commands when waiting for the un/suback response from + * the server. Values less than 5000 are not allowed. + * @param handle A valid client handle from a successful call to MQTTClient_create(). + * @param milliSeconds the maximum number of milliseconds to wait + * @return MQTTCLIENT_SUCCESS or MQTTCLIENT_FAILURE + */ +LIBMQTT_API int MQTTClient_setCommandTimeout(MQTTClient handle, unsigned long milliSeconds); + +/** + * Returns a pointer to the string representation of the error or NULL. + * + * Do not free after use. Returns NULL if the error code is unknown. + */ +LIBMQTT_API const char* MQTTClient_strerror(int code); + +#if defined(__cplusplus) + } +#endif + +#endif + +/*! + * @cond MQTTClient_main + * @page async Asynchronous vs synchronous client applications + * This client library supports two modes of operation. These are referred to + * as synchronous and asynchronous modes. If your application + * calls MQTTClient_setCallbacks(), this puts the client into asynchronous + * mode, otherwise it operates in synchronous mode. + * + * In synchronous mode, the client application runs on a single thread. + * Messages are published using the MQTTClient_publish() and + * MQTTClient_publishMessage() functions. To determine that a QoS1 or QoS2 + * (see @ref qos) message has been successfully delivered, the application + * must call the MQTTClient_waitForCompletion() function. An example showing + * synchronous publication is shown in @ref pubsync. Receiving messages in + * synchronous mode uses the MQTTClient_receive() function. Client applications + * must call either MQTTClient_receive() or MQTTClient_yield() relatively + * frequently in order to allow processing of acknowledgements and the MQTT + * "pings" that keep the network connection to the server alive. + * + * In asynchronous mode, the client application runs on several threads. The + * main program calls functions in the client library to publish and subscribe, + * just as for the synchronous mode. Processing of handshaking and maintaining + * the network connection is performed in the background, however. + * Notifications of status and message reception are provided to the client + * application using callbacks registered with the library by the call to + * MQTTClient_setCallbacks() (see MQTTClient_messageArrived(), + * MQTTClient_connectionLost() and MQTTClient_deliveryComplete()). + * This API is not thread safe however - it is not possible to call it from multiple + * threads without synchronization. You can use the MQTTAsync API for that. + * + * @page callbacks Callbacks + * You must not call a function from this API from within a callback otherwise + * a deadlock might result. The only exception to this is the ability to call + * connect within the connection lost callback, to allow a reconnect. + * + * When using MQTT 5.0, you can also call connect from within the disconnected + * callback, which is invoked when the MQTT server sends a disconnect packet. + * This server behaviour is allowed in MQTT 5.0, but not in MQTT 3.1.1, so the + * disconnected callback will never be invoked if you use MQTT 3.1.1. + * + * In particular, you must make a publish call within the message arrived callback. + * These restrictions are all lifted in the + * MQTTAsync API. + * + * If no callbacks are assigned, this will include the message arrived callback. + * This could be done if the application is a pure publisher, and does + * not subscribe to any topics. If however messages are received, and no message + * arrived callback is set, or receive not called, then those messages will accumulate + * and take up memory, as there is no place for them to be delivered. + * It is up to the application to protect against this situation. + * + * @page wildcard Subscription wildcards + * Every MQTT message includes a topic that classifies it. MQTT servers use + * topics to determine which subscribers should receive messages published to + * the server. + * + * Consider the server receiving messages from several environmental sensors. + * Each sensor publishes its measurement data as a message with an associated + * topic. Subscribing applications need to know which sensor originally + * published each received message. A unique topic is thus used to identify + * each sensor and measurement type. Topics such as SENSOR1TEMP, + * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very + * flexible. If additional sensors are added to the system at a later date, + * subscribing applications must be modified to receive them. + * + * To provide more flexibility, MQTT supports a hierarchical topic namespace. + * This allows application designers to organize topics to simplify their + * management. Levels in the hierarchy are delimited by the '/' character, + * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these + * hierarchical topics as already described. + * + * For subscriptions, two wildcard characters are supported: + *
    + *
  • A '#' character represents a complete sub-tree of the hierarchy and + * thus must be the last character in a subscription topic string, such as + * SENSOR/#. This will match any topic starting with SENSOR/, such as + * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.
  • + *
  • A '+' character represents a single level of the hierarchy and is + * used between delimiters. For example, SENSOR/+/TEMP will match + * SENSOR/1/TEMP and SENSOR/2/TEMP.
  • + *
+ * Publishers are not allowed to use the wildcard characters in their topic + * names. + * + * Deciding on your topic hierarchy is an important step in your system design. + * + * @page qos Quality of service + * The MQTT protocol provides three qualities of service for delivering + * messages between clients and servers: "at most once", "at least once" and + * "exactly once". + * + * Quality of service (QoS) is an attribute of an individual message being + * published. An application sets the QoS for a specific message by setting the + * MQTTClient_message.qos field to the required value. + * + * A subscribing client can set the maximum quality of service a server uses + * to send messages that match the client subscriptions. The + * MQTTClient_subscribe() and MQTTClient_subscribeMany() functions set this + * maximum. The QoS of a message forwarded to a subscriber thus might be + * different to the QoS given to the message by the original publisher. + * The lower of the two values is used to forward a message. + * + * The three levels are: + * + * QoS0, At most once: The message is delivered at most once, or it + * may not be delivered at all. Its delivery across the network is not + * acknowledged. The message is not stored. The message could be lost if the + * client is disconnected, or if the server fails. QoS0 is the fastest mode of + * transfer. It is sometimes called "fire and forget". + * + * The MQTT protocol does not require servers to forward publications at QoS0 + * to a client. If the client is disconnected at the time the server receives + * the publication, the publication might be discarded, depending on the + * server implementation. + * + * QoS1, At least once: The message is always delivered at least once. + * It might be delivered multiple times if there is a failure before an + * acknowledgment is received by the sender. The message must be stored + * locally at the sender, until the sender receives confirmation that the + * message has been published by the receiver. The message is stored in case + * the message must be sent again. + * + * QoS2, Exactly once: The message is always delivered exactly once. + * The message must be stored locally at the sender, until the sender receives + * confirmation that the message has been published by the receiver. The + * message is stored in case the message must be sent again. QoS2 is the + * safest, but slowest mode of transfer. A more sophisticated handshaking + * and acknowledgement sequence is used than for QoS1 to ensure no duplication + * of messages occurs. + * @page pubsync Synchronous publication example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + exit(EXIT_FAILURE); + } + + printf("Waiting for up to %d seconds for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID); + rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); + printf("Message with delivery token %d delivered\n", token); + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + printf("Failed to disconnect, return code %d\n", rc); + MQTTClient_destroy(&client); + return rc; +} + + * @endcode + * + * @page pubasync Asynchronous publication example +@code{.c} +#include +#include +#include +#include "MQTTClient.h" + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientPub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + pubmsg.payload = PAYLOAD; + pubmsg.payloadlen = (int)strlen(PAYLOAD); + pubmsg.qos = QOS; + pubmsg.retained = 0; + deliveredtoken = 0; + if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to publish message, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + printf("Waiting for publication of %s\n" + "on topic %s for client with ClientID: %s\n", + PAYLOAD, TOPIC, CLIENTID); + while (deliveredtoken != token) + { + #if defined(_WIN32) + Sleep(100); + #else + usleep(10000L); + #endif + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } + +destroy_exit: + MQTTClient_destroy(&client); + +exit: + return rc; +} + + * @endcode + * @page subasync Asynchronous subscription example +@code +#include +#include +#include +#include "MQTTClient.h" + +#define ADDRESS "tcp://mqtt.eclipse.org:1883" +#define CLIENTID "ExampleClientSub" +#define TOPIC "MQTT Examples" +#define PAYLOAD "Hello World!" +#define QOS 1 +#define TIMEOUT 10000L + +volatile MQTTClient_deliveryToken deliveredtoken; + +void delivered(void *context, MQTTClient_deliveryToken dt) +{ + printf("Message with token value %d delivery confirmed\n", dt); + deliveredtoken = dt; +} + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) +{ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + MQTTClient_freeMessage(&message); + MQTTClient_free(topicName); + return 1; +} + +void connlost(void *context, char *cause) +{ + printf("\nConnection lost\n"); + printf(" cause: %s\n", cause); +} + +int main(int argc, char* argv[]) +{ + MQTTClient client; + MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + int rc; + + if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + + if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to set callbacks, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + conn_opts.keepAliveInterval = 20; + conn_opts.cleansession = 1; + if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to connect, return code %d\n", rc); + rc = EXIT_FAILURE; + goto destroy_exit; + } + + printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" + "Press Q to quit\n\n", TOPIC, CLIENTID, QOS); + if ((rc = MQTTClient_subscribe(client, TOPIC, QOS)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to subscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + else + { + int ch; + do + { + ch = getchar(); + } while (ch!='Q' && ch != 'q'); + + if ((rc = MQTTClient_unsubscribe(client, TOPIC)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to unsubscribe, return code %d\n", rc); + rc = EXIT_FAILURE; + } + } + + if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to disconnect, return code %d\n", rc); + rc = EXIT_FAILURE; + } +destroy_exit: + MQTTClient_destroy(&client); +exit: + return rc; +} + + * @endcode + * @page tracing Tracing + * + * Runtime tracing is controlled by environment variables. + * + * Tracing is switched on by setting MQTT_C_CLIENT_TRACE. A value of ON, or stdout, prints to + * stdout, any other value is interpreted as a file name to use. + * + * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment + * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM + * (from least to most verbose). + * + * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output + * to a file. Two files are used at most, when they are full, the last one is overwritten with the + * new trace entries. The default size is 1000 lines. + * + * ### MQTT Packet Tracing + * + * A feature that can be very useful is printing the MQTT packets that are sent and received. To + * achieve this, use the following environment variable settings: + * @code + MQTT_C_CLIENT_TRACE=ON + MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL + * @endcode + * The output you should see looks like this: + * @code + 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0 + 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0) + 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1 + 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. socket number + * 4. client id + * 5. direction (-> from client to server, <- from server to client) + * 6. packet details + * + * ### Default Level Tracing + * + * This is an extract of a default level trace of a call to connect: + * @code + 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893 + 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716 + 20130528 160447.479 Connecting to serverURI localhost:1883 + 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98 + 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48 + 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73 + 20130528 160447.479 (1152206656) (3)> Socket_new:599 + 20130528 160447.479 New socket 4 for localhost, port 1883 + 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163 + 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73 + 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0) + 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0) + 20130528 160447.479 (1152206656) (4)> Socket_error:95 + 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115) + 20130528 160447.479 Connect pending + 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115) + 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115) + * @endcode + * where the fields are: + * 1. date + * 2. time + * 3. thread id + * 4. function nesting level + * 5. function entry (>) or exit (<) + * 6. function name : line of source code file + * 7. return value (if there is one) + * + * ### Memory Allocation Tracing + * + * Setting the trace level to maximum causes memory allocations and frees to be traced along with + * the default trace entries, with messages like the following: + * @code + 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930 + + 20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes + * @endcode + * When the last MQTT client object is destroyed, if the trace is being recorded + * and all memory allocated by the client library has not been freed, an error message will be + * written to the trace. This can help with fixing memory leaks. The message will look like this: + * @code + 20130528 163909.208 Some memory not freed at shutdown, possible memory leak + 20130528 163909.208 Heap scan start, total 880 bytes + 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00 + 20130528 163909.208 Content + 20130528 163909.209 Heap scan end + * @endcode + * @endcond + */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTClientPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTClientPersistence.h new file mode 100644 index 0000000..d3caae4 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTClientPersistence.h @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** + * @file + * \brief This structure represents a persistent data store, used to store + * outbound and inbound messages, in order to achieve reliable messaging. + * + * The MQTT Client persists QoS1 and QoS2 messages in order to meet the + * assurances of delivery associated with these @ref qos levels. The messages + * are saved in persistent storage + * The type and context of the persistence implementation are specified when + * the MQTT client is created (see MQTTClient_create()). The default + * persistence type (::MQTTCLIENT_PERSISTENCE_DEFAULT) uses a file system-based + * persistence mechanism. The persistence_context argument passed to + * MQTTClient_create() when using the default peristence is a string + * representing the location of the persistence directory. If the context + * argument is NULL, the working directory will be used. + * + * To use memory-based persistence, an application passes + * ::MQTTCLIENT_PERSISTENCE_NONE as the persistence_type to + * MQTTClient_create(). This can lead to message loss in certain situations, + * but can be appropriate in some cases (see @ref qos). + * + * Client applications can provide their own persistence mechanism by passing + * ::MQTTCLIENT_PERSISTENCE_USER as the persistence_type. To implement a + * custom persistence mechanism, the application must pass an initialized + * ::MQTTClient_persistence structure as the persistence_context + * argument to MQTTClient_create(). + * + * If the functions defined return an ::MQTTCLIENT_PERSISTENCE_ERROR then the + * state of the persisted data should remain as it was prior to the function + * being called. For example, if Persistence_put() returns + * ::MQTTCLIENT_PERSISTENCE_ERROR, then it is assumed tha tthe persistent store + * does not contain the data that was passed to the function. Similarly, if + * Persistence_remove() returns ::MQTTCLIENT_PERSISTENCE_ERROR then it is + * assumed that the data to be removed is still held in the persistent store. + * + * It is up to the persistence implementation to log any error information that + * may be required to diagnose a persistence mechanism failure. + */ + +/* +/// @cond EXCLUDE +*/ +#if !defined(MQTTCLIENTPERSISTENCE_H) +#define MQTTCLIENTPERSISTENCE_H +/* +/// @endcond +*/ + +/** + * This persistence_type value specifies the default file system-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_DEFAULT 0 +/** + * This persistence_type value specifies a memory-based + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_NONE 1 +/** + * This persistence_type value specifies an application-specific + * persistence mechanism (see MQTTClient_create()). + */ +#define MQTTCLIENT_PERSISTENCE_USER 2 + +/** + * Application-specific persistence functions must return this error code if + * there is a problem executing the function. + */ +#define MQTTCLIENT_PERSISTENCE_ERROR -2 + +/** + * @brief Initialize the persistent store. + * + * Either open the existing persistent store for this client ID or create a new + * one if one doesn't exist. If the persistent store is already open, return + * without taking any action. + * + * An application can use the same client identifier to connect to many + * different servers. The clientid in conjunction with the + * serverURI uniquely identifies the persistence store required. + * + * @param handle The address of a pointer to a handle for this persistence + * implementation. This function must set handle to a valid reference to the + * persistence following a successful return. + * The handle pointer is passed as an argument to all the other + * persistence functions. It may include the context parameter and/or any other + * data for use by the persistence functions. + * @param clientID The client identifier for which the persistent store should + * be opened. + * @param serverURI The connection string specified when the MQTT client was + * created (see MQTTClient_create()). + * @param context A pointer to any data required to initialize the persistent + * store (see ::MQTTClient_persistence). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_open)(void** handle, const char* clientID, const char* serverURI, void* context); + +/** + * @brief Close the persistent store referred to by the handle. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_close)(void* handle); + +/** + * @brief Put the specified data into the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string used as the key for the data to be put in the store. The + * key is later used to retrieve data from the store with Persistence_get(). + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers associated with + * this key. + * @param buflens An array of lengths of the data buffers. buflen[n] + * gives the length of buffer[n]. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_put)(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); + +/** + * @brief Retrieve the specified data from the persistent store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be retrieved. This is + * the same key used to save the data to the store with Persistence_put(). + * @param buffer The address of a pointer to a buffer. This function sets the + * pointer to point at the retrieved data, if successful. + * @param buflen The address of an int that is set to the length of + * buffer by this function if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_get)(void* handle, char* key, char** buffer, int* buflen); + +/** + * @brief Remove the data for the specified key from the store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key A string that is the key for the data to be removed from the + * store. This is the same key used to save the data to the store with + * Persistence_put(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_remove)(void* handle, char* key); + +/** + * @brief Returns the keys in this persistent data store. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param keys The address of a pointer to pointers to strings. Assuming + * successful execution, this function allocates memory to hold the returned + * keys (strings used to store the data with Persistence_put()). It also + * allocates memory to hold an array of pointers to these strings. keys + * is set to point to the array of pointers to strings. + * @param nkeys A pointer to the number of keys in this persistent data store. + * This function sets the number of keys, if successful. + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_keys)(void* handle, char*** keys, int* nkeys); + +/** + * @brief Clears the persistence store, so that it no longer contains any + * persisted data. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @return Return 0 if the function completes successfully, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_clear)(void* handle); + +/** + * @brief Returns whether any data has been persisted using the specified key. + * + * @param handle The handle pointer from a successful call to + * Persistence_open(). + * @param key The string to be tested for existence in the store. + * @return Return 0 if the key was found in the store, otherwise return + * ::MQTTCLIENT_PERSISTENCE_ERROR. + */ +typedef int (*Persistence_containskey)(void* handle, char* key); + +/** + * @brief A structure containing the function pointers to a persistence + * implementation and the context or state that will be shared across all + * the persistence functions. + */ +typedef struct { + /** + * A pointer to any data required to initialize the persistent store. + */ + void* context; + /** + * A function pointer to an implementation of Persistence_open(). + */ + Persistence_open popen; + /** + * A function pointer to an implementation of Persistence_close(). + */ + Persistence_close pclose; + /** + * A function pointer to an implementation of Persistence_put(). + */ + Persistence_put pput; + /** + * A function pointer to an implementation of Persistence_get(). + */ + Persistence_get pget; + /** + * A function pointer to an implementation of Persistence_remove(). + */ + Persistence_remove premove; + /** + * A function pointer to an implementation of Persistence_keys(). + */ + Persistence_keys pkeys; + /** + * A function pointer to an implementation of Persistence_clear(). + */ + Persistence_clear pclear; + /** + * A function pointer to an implementation of Persistence_containskey(). + */ + Persistence_containskey pcontainskey; +} MQTTClient_persistence; + + +/** + * A callback which is invoked just before a write to persistence. This can be + * used to transform the data, for instance to encrypt it. + * @param context The context as set in ::MQTTAsync_setBeforePersistenceWrite + * @param bufcount The number of buffers to write to the persistence store. + * @param buffers An array of pointers to the data buffers. + * @param buflens An array of lengths of the data buffers. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_beforeWrite(void* context, int bufcount, char* buffers[], int buflens[]); + + +/** + * A callback which is invoked just after a read from persistence. This can be + * used to transform the data, for instance to decrypt it. + * @param context The context as set in ::MQTTAsync_setAfterPersistenceRead + * @param buffer The address of a pointer to a buffer. + * @param buflen The address of an int that is the length of the buffer. + * @return Return 0 if the function completes successfully, otherwise non 0. + */ +typedef int MQTTPersistence_afterRead(void* context, char** buffer, int* buflen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTExportDeclarations.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTExportDeclarations.h new file mode 100644 index 0000000..d492ef1 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTExportDeclarations.h @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2020, 2020 Andreas Walter + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Andreas Walter - initially moved export declarations into separate fle + *******************************************************************************/ + +#if !defined(EXPORTDECLARATIONS_H) +#define EXPORTDECLARATIONS_H + +#if defined(_WIN32) || defined(_WIN64) +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __declspec(dllexport) +# elif defined(PAHO_MQTT_IMPORTS) +# define LIBMQTT_API __declspec(dllimport) +# else +# define LIBMQTT_API +# endif +#else +# if defined(PAHO_MQTT_EXPORTS) +# define LIBMQTT_API __attribute__ ((visibility ("default"))) +# else +# define LIBMQTT_API extern +# endif +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPacket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPacket.h new file mode 100644 index 0000000..658404a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPacket.h @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - big endian Linux reversed definition + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKET_H) +#define MQTTPACKET_H + +#include "Socket.h" +#if defined(OPENSSL) +#include "SSLSocket.h" +#endif +#include "LinkedList.h" +#include "Clients.h" + +typedef unsigned int bool; +typedef void* (*pf)(int, unsigned char, char*, size_t); + +#include "MQTTProperties.h" +#include "MQTTReasonCodes.h" + +enum errors +{ + MQTTPACKET_BAD = -4, + MQTTPACKET_BUFFER_TOO_SHORT = -2, + MQTTPACKET_READ_ERROR = -1, + MQTTPACKET_READ_COMPLETE +}; + + +enum msgTypes +{ + CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, + PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, + PINGREQ, PINGRESP, DISCONNECT, AUTH +}; + +#if defined(__linux__) +#include +#if __BYTE_ORDER == __BIG_ENDIAN + #define REVERSED 1 +#endif +#endif + +/** + * Bitfields for the MQTT header byte. + */ +typedef union +{ + /*unsigned*/ char byte; /**< the whole byte */ +#if defined(REVERSED) + struct + { + unsigned int type : 4; /**< message type nibble */ + bool dup : 1; /**< DUP flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool retain : 1; /**< retained flag bit */ + } bits; +#else + struct + { + bool retain : 1; /**< retained flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + bool dup : 1; /**< DUP flag bit */ + unsigned int type : 4; /**< message type nibble */ + } bits; +#endif +} Header; + + +/** + * Data for a connect packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connect flags */ +#if defined(REVERSED) + struct + { + bool username : 1; /**< 3.1 user name */ + bool password : 1; /**< 3.1 password */ + bool willRetain : 1; /**< will retain setting */ + unsigned int willQoS : 2; /**< will QoS value */ + bool will : 1; /**< will flag */ + bool cleanstart : 1; /**< cleansession flag */ + int : 1; /**< unused */ + } bits; +#else + struct + { + int : 1; /**< unused */ + bool cleanstart : 1; /**< cleansession flag */ + bool will : 1; /**< will flag */ + unsigned int willQoS : 2; /**< will QoS value */ + bool willRetain : 1; /**< will retain setting */ + bool password : 1; /**< 3.1 password */ + bool username : 1; /**< 3.1 user name */ + } bits; +#endif + } flags; /**< connect flags byte */ + + char *Protocol, /**< MQTT protocol name */ + *clientID, /**< string client id */ + *willTopic, /**< will topic */ + *willMsg; /**< will payload */ + + int keepAliveTimer; /**< keepalive timeout value in seconds */ + unsigned char version; /**< MQTT version number */ +} Connect; + + +/** + * Data for a connack packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + union + { + unsigned char all; /**< all connack flags */ +#if defined(REVERSED) + struct + { + unsigned int reserved : 7; /**< message type nibble */ + bool sessionPresent : 1; /**< was a session found on the server? */ + } bits; +#else + struct + { + bool sessionPresent : 1; /**< was a session found on the server? */ + unsigned int reserved : 7; /**< message type nibble */ + } bits; +#endif + } flags; /**< connack flags byte */ + unsigned char rc; /**< connack reason code */ + unsigned int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Connack; + + +/** + * Data for a packet with header only. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ +} MQTTPacket; + + +/** + * Data for a suback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* qoss; /**< list of granted QoSs (MQTT 3/4) / reason codes (MQTT 5) */ +} Suback; + + +/** + * Data for an MQTT V5 unsuback packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + List* reasonCodes; /**< list of reason codes */ +} Unsuback; + + +/** + * Data for a publish packet. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + char* topic; /**< topic string */ + int topiclen; + int msgId; /**< MQTT message id */ + char* payload; /**< binary payload, length delimited */ + int payloadlen; /**< payload length */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ + uint8_t mask[4]; /**< the websockets mask the payload is masked with, if any */ +} Publish; + + +/** + * Data for one of the ack packets. + */ +typedef struct +{ + Header header; /**< MQTT header byte */ + int msgId; /**< MQTT message id */ + unsigned char rc; /**< MQTT 5 reason code */ + int MQTTVersion; /**< the version of MQTT */ + MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ +} Ack; + +typedef Ack Puback; +typedef Ack Pubrec; +typedef Ack Pubrel; +typedef Ack Pubcomp; + +int MQTTPacket_encode(char* buf, size_t length); +int MQTTPacket_decode(networkHandles* net, size_t* value); +int readInt(char** pptr); +char* readUTF(char** pptr, char* enddata); +unsigned char readChar(char** pptr); +void writeChar(char** pptr, char c); +void writeInt(char** pptr, int anInt); +void writeUTF(char** pptr, const char* string); +void writeData(char** pptr, const void* data, int datalen); + +const char* MQTTPacket_name(int ptype); + +void* MQTTPacket_Factory(int MQTTVersion, networkHandles* net, int* error); +int MQTTPacket_send(networkHandles* net, Header header, char* buffer, size_t buflen, int free, int MQTTVersion); +int MQTTPacket_sends(networkHandles* net, Header header, PacketBuffers* buffers, int MQTTVersion); + +void* MQTTPacket_header_only(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +int MQTTPacket_send_disconnect(Clients* client, enum MQTTReasonCodes reason, MQTTProperties* props); + +void* MQTTPacket_publish(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freePublish(Publish* pack); +int MQTTPacket_send_publish(Publish* pack, int dup, int qos, int retained, networkHandles* net, const char* clientID); +int MQTTPacket_send_puback(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +void MQTTPacket_freeAck(Ack* pack); +void MQTTPacket_freeSuback(Suback* pack); +void MQTTPacket_freeUnsuback(Unsuback* pack); +int MQTTPacket_send_pubrec(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubrel(int MQTTVersion, int msgid, int dup, networkHandles* net, const char* clientID); +int MQTTPacket_send_pubcomp(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); + +void MQTTPacket_free_packet(MQTTPacket* pack); + +void writeInt4(char** pptr, int anInt); +int readInt4(char** pptr); +void writeMQTTLenString(char** pptr, MQTTLenString lenstring); +int MQTTLenStringRead(MQTTLenString* lenstring, char** pptr, char* enddata); +int MQTTPacket_VBIlen(int rem_len); +int MQTTPacket_decodeBuf(char* buf, unsigned int* value); + +#include "MQTTPacketOut.h" + +#endif /* MQTTPACKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPacketOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPacketOut.h new file mode 100644 index 0000000..d962554 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPacketOut.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPACKETOUT_H) +#define MQTTPACKETOUT_H + +#include "MQTTPacket.h" + +int MQTTPacket_send_connect(Clients* client, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +void* MQTTPacket_connack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); +void MQTTPacket_freeConnack(Connack* pack); + +int MQTTPacket_send_pingreq(networkHandles* net, const char* clientID); + +int MQTTPacket_send_subscribe(List* topics, List* qoss, MQTTSubscribe_options* opts, MQTTProperties* props, + int msgid, int dup, Clients* client); +void* MQTTPacket_suback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +int MQTTPacket_send_unsubscribe(List* topics, MQTTProperties* props, int msgid, int dup, Clients* client); +void* MQTTPacket_unsuback(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPersistence.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPersistence.h new file mode 100644 index 0000000..ed2e0ce --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPersistence.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - async client updates + * Ian Craggs - fix for bug 432903 - queue persistence + * Ian Craggs - MQTT V5 updates + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCE_H) +#define MQTTPERSISTENCE_H + +#if defined(__cplusplus) + extern "C" { +#endif + +#include "Clients.h" +#include "MQTTProperties.h" + +/** Stem of the key for a sent PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_PUBLISH_SENT "s-" +/** Stem of the key for a sent PUBREL */ +#define PERSISTENCE_PUBREL "sc-" +/** Stem of the key for a received PUBLISH QoS2 */ +#define PERSISTENCE_PUBLISH_RECEIVED "r-" + +/** Stem of the key for a sent MQTT V5 PUBLISH QoS1 or QoS2 */ +#define PERSISTENCE_V5_PUBLISH_SENT "s5-" +/** Stem of the key for a sent MQTT V5 PUBREL */ +#define PERSISTENCE_V5_PUBREL "sc5-" +/** Stem of the key for a received MQTT V5 PUBLISH QoS2 */ +#define PERSISTENCE_V5_PUBLISH_RECEIVED "r5-" + +/** Stem of the key for an async client command */ +#define PERSISTENCE_COMMAND_KEY "c-" +/** Stem of the key for an MQTT V5 async client command */ +#define PERSISTENCE_V5_COMMAND_KEY "c5-" +/** Stem of the key for an client incoming message queue */ +#define PERSISTENCE_QUEUE_KEY "q-" +/** Stem of the key for an MQTT V5 incoming message queue */ +#define PERSISTENCE_V5_QUEUE_KEY "q5-" +/** Maximum length of a stem for a persistence key */ +#define PERSISTENCE_MAX_STEM_LENGTH 3 +/** Maximum allowed length of a persistence key */ +#define PERSISTENCE_MAX_KEY_LENGTH 9 +/** Maximum size of an integer sequence number appended to a persistence key */ +#define PERSISTENCE_SEQNO_LIMIT 1000000 /*10^(PERSISTENCE_MAX_KEY_LENGTH - PERSISTENCE_MAX_STEM_LENGTH)*/ + +int MQTTPersistence_create(MQTTClient_persistence** per, int type, void* pcontext); +int MQTTPersistence_initialize(Clients* c, const char* serverURI); +int MQTTPersistence_close(Clients* c); +int MQTTPersistence_clear(Clients* c); +int MQTTPersistence_restorePackets(Clients* c); +void* MQTTPersistence_restorePacket(int MQTTVersion, char* buffer, size_t buflen); +void MQTTPersistence_insertInOrder(List* list, void* content, size_t size); +int MQTTPersistence_putPacket(int socket, char* buf0, size_t buf0len, int count, + char** buffers, size_t* buflens, int htype, int msgId, int scr, int MQTTVersion); +int MQTTPersistence_remove(Clients* c, char* type, int qos, int msgId); +void MQTTPersistence_wrapMsgID(Clients *c); + +typedef struct +{ + char struct_id[4]; + int struct_version; + int payloadlen; + void* payload; + int qos; + int retained; + int dup; + int msgid; + MQTTProperties properties; +} MQTTPersistence_message; + +typedef struct +{ + MQTTPersistence_message* msg; + char* topicName; + int topicLen; + unsigned int seqno; /* only used on restore */ +} MQTTPersistence_qEntry; + +int MQTTPersistence_unpersistQueueEntry(Clients* client, MQTTPersistence_qEntry* qe); +int MQTTPersistence_persistQueueEntry(Clients* aclient, MQTTPersistence_qEntry* qe); +int MQTTPersistence_restoreMessageQueue(Clients* c); +#ifdef __cplusplus + } +#endif + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPersistenceDefault.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPersistenceDefault.h new file mode 100644 index 0000000..506b4da --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTPersistenceDefault.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPERSISTENCEDEFAULT_H) +#define MQTTPERSISTENCEDEFAULT_H + +/** 8.3 filesystem */ +#define MESSAGE_FILENAME_LENGTH 8 +/** Extension of the filename */ +#define MESSAGE_FILENAME_EXTENSION ".msg" + +/* prototypes of the functions for the default file system persistence */ +int pstopen(void** handle, const char* clientID, const char* serverURI, void* context); +int pstclose(void* handle); +int pstput(void* handle, char* key, int bufcount, char* buffers[], int buflens[]); +int pstget(void* handle, char* key, char** buffer, int* buflen); +int pstremove(void* handle, char* key); +int pstkeys(void* handle, char*** keys, int* nkeys); +int pstclear(void* handle); +int pstcontainskey(void* handle, char* key); + +int pstmkdir(char *pPathname); + +#endif + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProperties.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProperties.h new file mode 100644 index 0000000..81b8e3a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProperties.h @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTPROPERTIES_H) +#define MQTTPROPERTIES_H + +#include "MQTTExportDeclarations.h" + +#define MQTT_INVALID_PROPERTY_ID -2 + +/** The one byte MQTT V5 property indicator */ +enum MQTTPropertyCodes { + MQTTPROPERTY_CODE_PAYLOAD_FORMAT_INDICATOR = 1, /**< The value is 1 */ + MQTTPROPERTY_CODE_MESSAGE_EXPIRY_INTERVAL = 2, /**< The value is 2 */ + MQTTPROPERTY_CODE_CONTENT_TYPE = 3, /**< The value is 3 */ + MQTTPROPERTY_CODE_RESPONSE_TOPIC = 8, /**< The value is 8 */ + MQTTPROPERTY_CODE_CORRELATION_DATA = 9, /**< The value is 9 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIER = 11, /**< The value is 11 */ + MQTTPROPERTY_CODE_SESSION_EXPIRY_INTERVAL = 17, /**< The value is 17 */ + MQTTPROPERTY_CODE_ASSIGNED_CLIENT_IDENTIFER = 18,/**< The value is 18 */ + MQTTPROPERTY_CODE_SERVER_KEEP_ALIVE = 19, /**< The value is 19 */ + MQTTPROPERTY_CODE_AUTHENTICATION_METHOD = 21, /**< The value is 21 */ + MQTTPROPERTY_CODE_AUTHENTICATION_DATA = 22, /**< The value is 22 */ + MQTTPROPERTY_CODE_REQUEST_PROBLEM_INFORMATION = 23,/**< The value is 23 */ + MQTTPROPERTY_CODE_WILL_DELAY_INTERVAL = 24, /**< The value is 24 */ + MQTTPROPERTY_CODE_REQUEST_RESPONSE_INFORMATION = 25,/**< The value is 25 */ + MQTTPROPERTY_CODE_RESPONSE_INFORMATION = 26, /**< The value is 26 */ + MQTTPROPERTY_CODE_SERVER_REFERENCE = 28, /**< The value is 28 */ + MQTTPROPERTY_CODE_REASON_STRING = 31, /**< The value is 31 */ + MQTTPROPERTY_CODE_RECEIVE_MAXIMUM = 33, /**< The value is 33*/ + MQTTPROPERTY_CODE_TOPIC_ALIAS_MAXIMUM = 34, /**< The value is 34 */ + MQTTPROPERTY_CODE_TOPIC_ALIAS = 35, /**< The value is 35 */ + MQTTPROPERTY_CODE_MAXIMUM_QOS = 36, /**< The value is 36 */ + MQTTPROPERTY_CODE_RETAIN_AVAILABLE = 37, /**< The value is 37 */ + MQTTPROPERTY_CODE_USER_PROPERTY = 38, /**< The value is 38 */ + MQTTPROPERTY_CODE_MAXIMUM_PACKET_SIZE = 39, /**< The value is 39 */ + MQTTPROPERTY_CODE_WILDCARD_SUBSCRIPTION_AVAILABLE = 40,/**< The value is 40 */ + MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIERS_AVAILABLE = 41,/**< The value is 41 */ + MQTTPROPERTY_CODE_SHARED_SUBSCRIPTION_AVAILABLE = 42/**< The value is 241 */ +}; + +/** + * Returns a printable string description of an MQTT V5 property code. + * @param value an MQTT V5 property code. + * @return the printable string description of the input property code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTPropertyName(enum MQTTPropertyCodes value); + +/** The one byte MQTT V5 property type */ +enum MQTTPropertyTypes { + MQTTPROPERTY_TYPE_BYTE, + MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER, + MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER, + MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER, + MQTTPROPERTY_TYPE_BINARY_DATA, + MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING, + MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR +}; + +/** + * Returns the MQTT V5 type code of an MQTT V5 property. + * @param value an MQTT V5 property code. + * @return the MQTT V5 type code of the input property. -1 if the code was not found. + */ +LIBMQTT_API int MQTTProperty_getType(enum MQTTPropertyCodes value); + +/** + * The data for a length delimited string + */ +typedef struct +{ + int len; /**< the length of the string */ + char* data; /**< pointer to the string data */ +} MQTTLenString; + + +/** + * Structure to hold an MQTT version 5 property of any type + */ +typedef struct +{ + enum MQTTPropertyCodes identifier; /**< The MQTT V5 property id. A multi-byte integer. */ + /** The value of the property, as a union of the different possible types. */ + union { + unsigned char byte; /**< holds the value of a byte property type */ + unsigned short integer2; /**< holds the value of a 2 byte integer property type */ + unsigned int integer4; /**< holds the value of a 4 byte integer property type */ + struct { + MQTTLenString data; /**< The value of a string property, or the name of a user property. */ + MQTTLenString value; /**< The value of a user property. */ + }; + } value; +} MQTTProperty; + +/** + * MQTT version 5 property list + */ +typedef struct MQTTProperties +{ + int count; /**< number of property entries in the array */ + int max_count; /**< max number of properties that the currently allocated array can store */ + int length; /**< mbi: byte length of all properties */ + MQTTProperty *array; /**< array of properties */ +} MQTTProperties; + +#define MQTTProperties_initializer {0, 0, 0, NULL} + +/** + * Returns the length of the properties structure when serialized ready for network transmission. + * @param props an MQTT V5 property structure. + * @return the length in bytes of the properties when serialized. + */ +int MQTTProperties_len(MQTTProperties* props); + +/** + * Add a property pointer to the property array. There is no memory allocation. + * @param props The property list to add the property to. + * @param prop The property to add to the list. + * @return 0 on success, -1 on failure. + */ +LIBMQTT_API int MQTTProperties_add(MQTTProperties* props, const MQTTProperty* prop); + +/** + * Serialize the given property list to a character buffer, e.g. for writing to the network. + * @param pptr pointer to the buffer - move the pointer as we add data + * @param properties pointer to the property list, can be NULL + * @return whether the write succeeded or not: number of bytes written, or < 0 on failure. + */ +int MQTTProperties_write(char** pptr, const MQTTProperties* properties); + +/** + * Reads a property list from a character buffer into an array. + * @param properties pointer to the property list to be filled. Should be initalized but empty. + * @param pptr pointer to the character buffer. + * @param enddata pointer to the end of the character buffer so we don't read beyond. + * @return 1 if the properties were read successfully. + */ +int MQTTProperties_read(MQTTProperties* properties, char** pptr, char* enddata); + +/** + * Free all memory allocated to the property list, including any to individual properties. + * @param properties pointer to the property list. + */ +LIBMQTT_API void MQTTProperties_free(MQTTProperties* properties); + +/** + * Copy the contents of a property list, allocating additional memory if needed. + * @param props pointer to the property list. + * @return the duplicated property list. + */ +LIBMQTT_API MQTTProperties MQTTProperties_copy(const MQTTProperties* props); + +/** + * Checks if property list contains a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return 1 if found, 0 if not. + */ +LIBMQTT_API int MQTTProperties_hasProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the number of instances of a property id. Most properties can exist only once. + * User properties and subscription ids can exist more than once. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the number of times found. Can be 0. + */ +LIBMQTT_API int MQTTProperties_propertyCount(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property. The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValue(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns the integer value of a specific property when it's not the only instance. + * The property given must be a numeric type. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the integer value of the property. -9999999 on failure. + */ +LIBMQTT_API int MQTTProperties_getNumericValueAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +/** + * Returns a pointer to the property structure for a specific property. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getProperty(MQTTProperties *props, enum MQTTPropertyCodes propid); + +/** + * Returns a pointer to the property structure for a specific property when it's not the only instance. + * @param props pointer to the property list. + * @param propid the property id to check for. + * @param index the instance number, starting at 0. + * @return the pointer to the property structure if found. NULL if not found. + */ +LIBMQTT_API MQTTProperty* MQTTProperties_getPropertyAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index); + +#endif /* MQTTPROPERTIES_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProtocol.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProtocol.h new file mode 100644 index 0000000..52bcd15 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProtocol.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2009, 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - MQTT 3.1.1 updates + *******************************************************************************/ + +#if !defined(MQTTPROTOCOL_H) +#define MQTTPROTOCOL_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +typedef struct +{ + int socket; + Publications* p; +} pending_write; + + +typedef struct +{ + List publications; + unsigned int msgs_received; + unsigned int msgs_sent; + List pending_writes; /* for qos 0 writes not complete */ +} MQTTProtocol; + + +#include "MQTTProtocolOut.h" + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProtocolClient.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProtocolClient.h new file mode 100644 index 0000000..2d077af --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProtocolClient.h @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 updates + * Rong Xiang, Ian Craggs - C++ compatibility + * Ian Craggs - add debug definition of MQTTStrdup for when needed + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLCLIENT_H) +#define MQTTPROTOCOLCLIENT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Log.h" +#include "MQTTProtocol.h" +#include "Messages.h" +#include "MQTTProperties.h" + +#define MAX_MSG_ID 65535 +#define MAX_CLIENTID_LEN 65535 + +int MQTTProtocol_startPublish(Clients* pubclient, Publish* publish, int qos, int retained, Messages** m); +Messages* MQTTProtocol_createMessage(Publish* publish, Messages** mm, int qos, int retained, int allocatePayload); +Publications* MQTTProtocol_storePublication(Publish* publish, int* len); +int messageIDCompare(void* a, void* b); +int MQTTProtocol_assignMsgId(Clients* client); +void MQTTProtocol_removePublication(Publications* p); +void Protocol_processPublication(Publish* publish, Clients* client, int allocatePayload); + +int MQTTProtocol_handlePublishes(void* pack, int sock); +int MQTTProtocol_handlePubacks(void* pack, int sock); +int MQTTProtocol_handlePubrecs(void* pack, int sock); +int MQTTProtocol_handlePubrels(void* pack, int sock); +int MQTTProtocol_handlePubcomps(void* pack, int sock); + +void MQTTProtocol_closeSession(Clients* c, int sendwill); +void MQTTProtocol_keepalive(START_TIME_TYPE); +void MQTTProtocol_retry(START_TIME_TYPE, int, int); +void MQTTProtocol_freeClient(Clients* client); +void MQTTProtocol_emptyMessageList(List* msgList); +void MQTTProtocol_freeMessageList(List* msgList); + +char* MQTTStrncpy(char *dest, const char* src, size_t num); +char* MQTTStrdup(const char* src); + +//#define MQTTStrdup(src) MQTTStrncpy(malloc(strlen(src)+1), src, strlen(src)+1) + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProtocolOut.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProtocolOut.h new file mode 100644 index 0000000..6a50155 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTProtocolOut.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + * Ian Craggs - MQTT 3.1.1 support + * Ian Craggs - SNI support + * Ian Craggs - MQTT 5.0 support + *******************************************************************************/ + +#if !defined(MQTTPROTOCOLOUT_H) +#define MQTTPROTOCOLOUT_H + +#include "LinkedList.h" +#include "MQTTPacket.h" +#include "Clients.h" +#include "Log.h" +#include "Messages.h" +#include "MQTTProtocol.h" +#include "MQTTProtocolClient.h" + +#define MQTT_DEFAULT_PORT 1883 +#define SECURE_MQTT_DEFAULT_PORT 8883 +#define WS_DEFAULT_PORT 80 + +size_t MQTTProtocol_addressPort(const char* uri, int* port, const char **topic, int default_port); +void MQTTProtocol_reconnect(const char* ip_address, Clients* client); +#if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#else +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#endif +int MQTTProtocol_handlePingresps(void* pack, int sock); +int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, int msgID, + MQTTSubscribe_options* opts, MQTTProperties* props); +int MQTTProtocol_handleSubacks(void* pack, int sock); +int MQTTProtocol_unsubscribe(Clients* client, List* topics, int msgID, MQTTProperties* props); +int MQTTProtocol_handleUnsubacks(void* pack, int sock); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTReasonCodes.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTReasonCodes.h new file mode 100644 index 0000000..2dc08ea --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTReasonCodes.h @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2017, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTREASONCODES_H) +#define MQTTREASONCODES_H + +#include "MQTTExportDeclarations.h" + +/** The MQTT V5 one byte reason code */ +enum MQTTReasonCodes { + MQTTREASONCODE_SUCCESS = 0, + MQTTREASONCODE_NORMAL_DISCONNECTION = 0, + MQTTREASONCODE_GRANTED_QOS_0 = 0, + MQTTREASONCODE_GRANTED_QOS_1 = 1, + MQTTREASONCODE_GRANTED_QOS_2 = 2, + MQTTREASONCODE_DISCONNECT_WITH_WILL_MESSAGE = 4, + MQTTREASONCODE_NO_MATCHING_SUBSCRIBERS = 16, + MQTTREASONCODE_NO_SUBSCRIPTION_FOUND = 17, + MQTTREASONCODE_CONTINUE_AUTHENTICATION = 24, + MQTTREASONCODE_RE_AUTHENTICATE = 25, + MQTTREASONCODE_UNSPECIFIED_ERROR = 128, + MQTTREASONCODE_MALFORMED_PACKET = 129, + MQTTREASONCODE_PROTOCOL_ERROR = 130, + MQTTREASONCODE_IMPLEMENTATION_SPECIFIC_ERROR = 131, + MQTTREASONCODE_UNSUPPORTED_PROTOCOL_VERSION = 132, + MQTTREASONCODE_CLIENT_IDENTIFIER_NOT_VALID = 133, + MQTTREASONCODE_BAD_USER_NAME_OR_PASSWORD = 134, + MQTTREASONCODE_NOT_AUTHORIZED = 135, + MQTTREASONCODE_SERVER_UNAVAILABLE = 136, + MQTTREASONCODE_SERVER_BUSY = 137, + MQTTREASONCODE_BANNED = 138, + MQTTREASONCODE_SERVER_SHUTTING_DOWN = 139, + MQTTREASONCODE_BAD_AUTHENTICATION_METHOD = 140, + MQTTREASONCODE_KEEP_ALIVE_TIMEOUT = 141, + MQTTREASONCODE_SESSION_TAKEN_OVER = 142, + MQTTREASONCODE_TOPIC_FILTER_INVALID = 143, + MQTTREASONCODE_TOPIC_NAME_INVALID = 144, + MQTTREASONCODE_PACKET_IDENTIFIER_IN_USE = 145, + MQTTREASONCODE_PACKET_IDENTIFIER_NOT_FOUND = 146, + MQTTREASONCODE_RECEIVE_MAXIMUM_EXCEEDED = 147, + MQTTREASONCODE_TOPIC_ALIAS_INVALID = 148, + MQTTREASONCODE_PACKET_TOO_LARGE = 149, + MQTTREASONCODE_MESSAGE_RATE_TOO_HIGH = 150, + MQTTREASONCODE_QUOTA_EXCEEDED = 151, + MQTTREASONCODE_ADMINISTRATIVE_ACTION = 152, + MQTTREASONCODE_PAYLOAD_FORMAT_INVALID = 153, + MQTTREASONCODE_RETAIN_NOT_SUPPORTED = 154, + MQTTREASONCODE_QOS_NOT_SUPPORTED = 155, + MQTTREASONCODE_USE_ANOTHER_SERVER = 156, + MQTTREASONCODE_SERVER_MOVED = 157, + MQTTREASONCODE_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158, + MQTTREASONCODE_CONNECTION_RATE_EXCEEDED = 159, + MQTTREASONCODE_MAXIMUM_CONNECT_TIME = 160, + MQTTREASONCODE_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161, + MQTTREASONCODE_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162 +}; + +/** + * Returns a printable string description of an MQTT V5 reason code. + * @param value an MQTT V5 reason code. + * @return the printable string description of the input reason code. + * NULL if the code was not found. + */ +LIBMQTT_API const char* MQTTReasonCode_toString(enum MQTTReasonCodes value); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTSubscribeOpts.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTSubscribeOpts.h new file mode 100644 index 0000000..264e4d0 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTSubscribeOpts.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(SUBOPTS_H) +#define SUBOPTS_H + +/** The MQTT V5 subscribe options, apart from QoS which existed before V5. */ +typedef struct MQTTSubscribe_options +{ + /** The eyecatcher for this structure. Must be MQSO. */ + char struct_id[4]; + /** The version number of this structure. Must be 0. + */ + int struct_version; + /** To not receive our own publications, set to 1. + * 0 is the original MQTT behaviour - all messages matching the subscription are received. + */ + unsigned char noLocal; + /** To keep the retain flag as on the original publish message, set to 1. + * If 0, defaults to the original MQTT behaviour where the retain flag is only set on + * publications sent by a broker if in response to a subscribe request. + */ + unsigned char retainAsPublished; + /** 0 - send retained messages at the time of the subscribe (original MQTT behaviour) + * 1 - send retained messages on subscribe only if the subscription is new + * 2 - do not send retained messages at all + */ + unsigned char retainHandling; +} MQTTSubscribe_options; + +#define MQTTSubscribe_options_initializer { {'M', 'Q', 'S', 'O'}, 0, 0, 0, 0 } + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTTime.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTTime.h new file mode 100644 index 0000000..8bd6860 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/MQTTTime.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + *******************************************************************************/ + +#if !defined(MQTTTIME_H) +#define MQTTTIME_H + +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#if WINVER >= _WIN32_WINNT_VISTA +#define START_TIME_TYPE ULONGLONG +#define START_TIME_ZERO 0 +#else +#define START_TIME_TYPE DWORD +#define START_TIME_ZERO 0 +#endif +#elif defined(AIX) +#define START_TIME_TYPE struct timespec +#define START_TIME_ZERO {0, 0} +#else +#include +#define START_TIME_TYPE struct timeval +#define START_TIME_ZERO {0, 0} +#endif + +#define ELAPSED_TIME_TYPE uint64_t +#define DIFF_TIME_TYPE int64_t + +void MQTTTime_sleep(ELAPSED_TIME_TYPE milliseconds); +START_TIME_TYPE MQTTTime_start_clock(void); +START_TIME_TYPE MQTTTime_now(void); +ELAPSED_TIME_TYPE MQTTTime_elapsed(START_TIME_TYPE milliseconds); +DIFF_TIME_TYPE MQTTTime_difftime(START_TIME_TYPE new, START_TIME_TYPE old); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Messages.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Messages.h new file mode 100644 index 0000000..58f5eae --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Messages.h @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MESSAGES_H) +#define MESSAGES_H + +#include "Log.h" + +const char* Messages_get(int, enum LOG_LEVELS); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/OsWrapper.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/OsWrapper.h new file mode 100644 index 0000000..96b629d --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/OsWrapper.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016, 2017 logi.cals GmbH + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Gunter Raidl - timer support for VxWorks + * Rainer Poisel - reusability + *******************************************************************************/ + +#if !defined(OSWRAPPER_H) +#define OSWRAPPER_H + +#if defined(_WRS_KERNEL) +#include + +#define lstat stat + +typedef unsigned long useconds_t; +void usleep(useconds_t useconds); + +#define timersub(a, b, result) \ + do \ + { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) \ + { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000L; \ + } \ + } while (0) +#endif /* defined(_WRS_KERNEL) */ + +#endif /* OSWRAPPER_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/SHA1.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/SHA1.h new file mode 100644 index 0000000..3ae2f0a --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/SHA1.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2018, 2019 Wind River Systems, Inc. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(SHA1_H) +#define SHA1_H + +#if defined(OPENSSL) +#include + +/** SHA-1 Digest Length */ +#define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH + +#else /* if defined(OPENSSL) */ + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +typedef struct SHA_CTX_S +{ + HCRYPTPROV hProv; + HCRYPTHASH hHash; +} SHA_CTX; +#else /* if defined(_WIN32) || defined(_WIN64) */ + +#include +typedef struct SHA_CTX_S { + uint32_t h[5]; + union { + uint32_t w[16]; + uint8_t buffer[64]; + }; + unsigned int size; + unsigned int total; +} SHA_CTX; +#endif /* else if defined(_WIN32) || defined(_WIN64) */ + +#include + +/** SHA-1 Digest Length (number of bytes in SHA1) */ +#define SHA1_DIGEST_LENGTH (160/8) + +/** + * Initializes the SHA1 hashing algorithm + * + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Update + * @see SHA1_Final + */ +int SHA1_Init(SHA_CTX *ctx); + +/** + * Updates a block to the SHA1 hash + * + * @param[in,out] ctx hashing context structure + * @param[in] data block of data to hash + * @param[in] len length of block to hash + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Update(SHA_CTX *ctx, const void *data, size_t len); + +/** + * Produce final SHA1 hash + * + * @param[out] md SHA1 hash produced (must be atleast + * @p SHA1_DIGEST_LENGTH in length) + * @param[in,out] ctx hashing context structure + * + * @see SHA1_Init + * @see SHA1_Final + */ +int SHA1_Final(unsigned char *md, SHA_CTX *ctx); + +#endif /* if defined(OPENSSL) */ +#endif /* SHA1_H */ + diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/SSLSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/SSLSocket.h new file mode 100644 index 0000000..86273c8 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/SSLSocket.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs, Allan Stockdill-Mander - initial implementation + * Ian Craggs - SNI support + * Ian Craggs - post connect checks and CApath + *******************************************************************************/ +#if !defined(SSLSOCKET_H) +#define SSLSOCKET_H + +#if defined(_WIN32) || defined(_WIN64) + #define ssl_mutex_type HANDLE +#else + #include + #include + #define ssl_mutex_type pthread_mutex_t +#endif + +#include +#include "SocketBuffer.h" +#include "Clients.h" + +#define URI_SSL "ssl://" + +/** if we should handle openssl initialization (bool_value == 1) or depend on it to be initalized externally (bool_value == 0) */ +void SSLSocket_handleOpensslInit(int bool_value); + +int SSLSocket_initialize(void); +void SSLSocket_terminate(void); +int SSLSocket_setSocketForSSL(networkHandles* net, MQTTClient_SSLOptions* opts, const char* hostname, size_t hostname_len); + +int SSLSocket_getch(SSL* ssl, int socket, char* c); +char *SSLSocket_getdata(SSL* ssl, int socket, size_t bytes, size_t* actual_len, int* rc); + +int SSLSocket_close(networkHandles* net); +int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +int SSLSocket_connect(SSL* ssl, int sock, const char* hostname, int verify, int (*cb)(const char *str, size_t len, void *u), void* u); + +int SSLSocket_getPendingRead(void); +int SSLSocket_continueWrite(pending_writes* pw); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Socket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Socket.h new file mode 100644 index 0000000..39a8158 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Socket.h @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + * Ian Craggs - async client updates + *******************************************************************************/ + +#if !defined(SOCKET_H) +#define SOCKET_H + +#include +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#include +#define MAXHOSTNAMELEN 256 +#if !defined(SSLSOCKET_H) +#undef EAGAIN +#define EAGAIN WSAEWOULDBLOCK +#undef EINTR +#define EINTR WSAEINTR +#undef EINPROGRESS +#define EINPROGRESS WSAEINPROGRESS +#undef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#undef ENOTCONN +#define ENOTCONN WSAENOTCONN +#undef ECONNRESET +#define ECONNRESET WSAECONNRESET +#undef ETIMEDOUT +#define ETIMEDOUT WAIT_TIMEOUT +#endif +#define ioctl ioctlsocket +#define socklen_t int +#else +#define INVALID_SOCKET SOCKET_ERROR +#include +#if !defined(_WRS_KERNEL) +#include +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define ULONG size_t +#endif + +#include "mutex_type.h" /* Needed for mutex_type */ + +/** socket operation completed successfully */ +#define TCPSOCKET_COMPLETE 0 +#if !defined(SOCKET_ERROR) + /** error in socket operation */ + #define SOCKET_ERROR -1 +#endif +/** must be the same as SOCKETBUFFER_INTERRUPTED */ +#define TCPSOCKET_INTERRUPTED -22 +#define SSL_FATAL -3 + +#if !defined(INET6_ADDRSTRLEN) +#define INET6_ADDRSTRLEN 46 /** only needed for gcc/cygwin on windows */ +#endif + + +#if !defined(max) +#define max(A,B) ( (A) > (B) ? (A):(B)) +#endif + +#include "LinkedList.h" + +/* + * Network write buffers for an MQTT packet + */ +typedef struct +{ + int count; /**> number of buffers/buflens/frees */ + char** buffers; /**> array of byte buffers */ + size_t* buflens; /**> array of lengths of buffers */ + int* frees; /**> array of flags indicating whether each buffer needs to be freed */ + uint8_t mask[4]; /**> websocket mask used to mask the buffer data, if any */ +} PacketBuffers; + + +/** + * Structure to hold all socket data for the module + */ +typedef struct +{ + fd_set rset, /**< socket read set (see select doc) */ + rset_saved; /**< saved socket read set */ + int maxfdp1; /**< max descriptor used +1 (again see select doc) */ + List* clientsds; /**< list of client socket descriptors */ + ListElement* cur_clientsds; /**< current client socket descriptor (iterator) */ + List* connect_pending; /**< list of sockets for which a connect is pending */ + List* write_pending; /**< list of sockets for which a write is pending */ + fd_set pending_wset; /**< socket pending write set for select */ +} Sockets; + + +void Socket_outInitialize(void); +void Socket_outTerminate(void); +int Socket_getReadySocket(int more_work, struct timeval *tp, mutex_type mutex, int* rc); +int Socket_getch(int socket, char* c); +char *Socket_getdata(int socket, size_t bytes, size_t* actual_len, int* rc); +int Socket_putdatas(int socket, char* buf0, size_t buf0len, PacketBuffers bufs); +void Socket_close(int socket); +#if defined(__GNUC__) && defined(__linux__) +/* able to use GNU's getaddrinfo_a to make timeouts possible */ +int Socket_new(const char* addr, size_t addr_len, int port, int* socket, long timeout); +#else +int Socket_new(const char* addr, size_t addr_len, int port, int* socket); +#endif + +int Socket_noPendingWrites(int socket); +char* Socket_getpeer(int sock); + +void Socket_addPendingWrite(int socket); +void Socket_clearPendingWrite(int socket); + +typedef void Socket_writeComplete(int socket, int rc); +void Socket_setWriteCompleteCallback(Socket_writeComplete*); + +#endif /* SOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/SocketBuffer.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/SocketBuffer.h new file mode 100644 index 0000000..0fc7d6e --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/SocketBuffer.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs, Allan Stockdill-Mander - SSL updates + *******************************************************************************/ + +#if !defined(SOCKETBUFFER_H) +#define SOCKETBUFFER_H + +#if defined(_WIN32) || defined(_WIN64) +#include +#else +#include +#endif + +#if defined(OPENSSL) +#include +#endif + +#if defined(_WIN32) || defined(_WIN64) + typedef WSABUF iobuf; +#else + typedef struct iovec iobuf; +#endif + +typedef struct +{ + int socket; + unsigned int index; + size_t headerlen; + char fixed_header[5]; /**< header plus up to 4 length bytes */ + size_t buflen, /**< total length of the buffer */ + datalen; /**< current length of data in buf */ + char* buf; +} socket_queue; + +typedef struct +{ + int socket, count; + size_t total; +#if defined(OPENSSL) + SSL* ssl; +#endif + size_t bytes; + iobuf iovecs[5]; + int frees[5]; +} pending_writes; + +#define SOCKETBUFFER_COMPLETE 0 +#if !defined(SOCKET_ERROR) + #define SOCKET_ERROR -1 +#endif +#define SOCKETBUFFER_INTERRUPTED -22 /* must be the same value as TCPSOCKET_INTERRUPTED */ + +int SocketBuffer_initialize(void); +void SocketBuffer_terminate(void); +void SocketBuffer_cleanup(int socket); +char* SocketBuffer_getQueuedData(int socket, size_t bytes, size_t* actual_len); +int SocketBuffer_getQueuedChar(int socket, char* c); +void SocketBuffer_interrupted(int socket, size_t actual_len); +char* SocketBuffer_complete(int socket); +void SocketBuffer_queueChar(int socket, char c); + +#if defined(OPENSSL) +int SocketBuffer_pendingWrite(int socket, SSL* ssl, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#else +int SocketBuffer_pendingWrite(int socket, int count, iobuf* iovecs, int* frees, size_t total, size_t bytes); +#endif +pending_writes* SocketBuffer_getWrite(int socket); +int SocketBuffer_writeComplete(int socket); +pending_writes* SocketBuffer_updateWrite(int socket, char* topic, char* payload); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/StackTrace.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/StackTrace.h new file mode 100644 index 0000000..c4f0d43 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/StackTrace.h @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#ifndef STACKTRACE_H_ +#define STACKTRACE_H_ + +#if defined(HIGH_PERFORMANCE) +#define NOSTACKTRACE 1 +#endif + +#include +#include "Log.h" +#include "Thread.h" + +#if defined(NOSTACKTRACE) +#define FUNC_ENTRY +#define FUNC_ENTRY_NOLOG +#define FUNC_ENTRY_MED +#define FUNC_ENTRY_MAX +#define FUNC_EXIT +#define FUNC_EXIT_NOLOG +#define FUNC_EXIT_MED +#define FUNC_EXIT_MAX +#define FUNC_EXIT_RC(x) +#define FUNC_EXIT_MED_RC(x) +#define FUNC_EXIT_MAX_RC(x) +#else +#if defined(_WIN32) || defined(_WIN64) +#define inline __inline +#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM) +#else +#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM) +#endif +#endif + +void StackTrace_entry(const char* name, int line, enum LOG_LEVELS trace); +void StackTrace_exit(const char* name, int line, void* return_value, enum LOG_LEVELS trace); + +void StackTrace_printStack(FILE* dest); +char* StackTrace_get(thread_id_type, char* buf, int bufsize); + +#endif /* STACKTRACE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Thread.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Thread.h new file mode 100644 index 0000000..29903f5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Thread.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2009, 2020 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation + * Ian Craggs, Allan Stockdill-Mander - async client updates + * Ian Craggs - fix for bug #420851 + * Ian Craggs - change MacOS semaphore implementation + *******************************************************************************/ + +#if !defined(THREAD_H) +#define THREAD_H + +#include "MQTTExportDeclarations.h" + +#include "MQTTClient.h" + +#include "mutex_type.h" /* Needed for mutex_type */ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define thread_type HANDLE + #define thread_id_type DWORD + #define thread_return_type DWORD + #define thread_fn LPTHREAD_START_ROUTINE + #define cond_type HANDLE + #define sem_type HANDLE + #undef ETIMEDOUT + #define ETIMEDOUT WSAETIMEDOUT +#else + #include + + #define thread_type pthread_t + #define thread_id_type pthread_t + #define thread_return_type void* + typedef thread_return_type (*thread_fn)(void*); + typedef struct { pthread_cond_t cond; pthread_mutex_t mutex; } cond_type_struct; + typedef cond_type_struct *cond_type; + #if defined(OSX) + #include + typedef dispatch_semaphore_t sem_type; + #else + #include + typedef sem_t *sem_type; + #endif + + cond_type Thread_create_cond(int*); + int Thread_signal_cond(cond_type); + int Thread_wait_cond(cond_type condvar, int timeout); + int Thread_destroy_cond(cond_type); +#endif + +LIBMQTT_API thread_type Thread_start(thread_fn, void*); + +LIBMQTT_API mutex_type Thread_create_mutex(int*); +LIBMQTT_API int Thread_lock_mutex(mutex_type); +LIBMQTT_API int Thread_unlock_mutex(mutex_type); +int Thread_destroy_mutex(mutex_type); + +LIBMQTT_API thread_id_type Thread_getid(); + +sem_type Thread_create_sem(int*); +int Thread_wait_sem(sem_type sem, int timeout); +int Thread_check_sem(sem_type sem); +int Thread_post_sem(sem_type sem); +int Thread_destroy_sem(sem_type sem); + + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Tree.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Tree.h new file mode 100644 index 0000000..dfd70ab --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/Tree.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial implementation and documentation + *******************************************************************************/ + + +#if !defined(TREE_H) +#define TREE_H + +#include /* for size_t definition */ + +/*BE +defm defTree(T) // macro to define a tree + +def T concat Node +{ + n32 ptr T concat Node "parent" + n32 ptr T concat Node "left" + n32 ptr T concat Node "right" + n32 ptr T id2str(T) + n32 suppress "size" +} + + +def T concat Tree +{ + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + struct + { + n32 ptr T concat Node suppress "root" + n32 ptr DATA suppress "compare" + } + n32 dec "count" + n32 dec suppress "size" +} + +endm + +defTree(INT) +defTree(STRING) +defTree(TMP) + +BE*/ + +/** + * Structure to hold all data for one list element + */ +typedef struct NodeStruct +{ + struct NodeStruct *parent, /**< pointer to parent tree node, in case we need it */ + *child[2]; /**< pointers to child tree nodes 0 = left, 1 = right */ + void* content; /**< pointer to element content */ + size_t size; /**< size of content */ + unsigned int red : 1; +} Node; + + +/** + * Structure to hold all data for one tree + */ +typedef struct +{ + struct + { + Node *root; /**< root node pointer */ + int (*compare)(void*, void*, int); /**< comparison function */ + } index[2]; + int indexes, /**< no of indexes into tree */ + count; /**< no of items */ + size_t size; /**< heap storage used */ + unsigned int heap_tracking : 1; /**< switch on heap tracking for this tree? */ + unsigned int allow_duplicates : 1; /**< switch to allow duplicate entries */ +} Tree; + + +Tree* TreeInitialize(int(*compare)(void*, void*, int)); +void TreeInitializeNoMalloc(Tree* aTree, int(*compare)(void*, void*, int)); +void TreeAddIndex(Tree* aTree, int(*compare)(void*, void*, int)); + +void* TreeAdd(Tree* aTree, void* content, size_t size); + +void* TreeRemove(Tree* aTree, void* content); + +void* TreeRemoveKey(Tree* aTree, void* key); +void* TreeRemoveKeyIndex(Tree* aTree, void* key, int index); + +void* TreeRemoveNodeIndex(Tree* aTree, Node* aNode, int index); + +void TreeFree(Tree* aTree); + +Node* TreeFind(Tree* aTree, void* key); +Node* TreeFindIndex(Tree* aTree, void* key, int index); + +Node* TreeNextElement(Tree* aTree, Node* curnode); + +int TreeIntCompare(void* a, void* b, int); +int TreePtrCompare(void* a, void* b, int); +int TreeStringCompare(void* a, void* b, int); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/VersionInfo.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/VersionInfo.h new file mode 100644 index 0000000..b3b3e78 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/VersionInfo.h @@ -0,0 +1,7 @@ +#ifndef VERSIONINFO_H +#define VERSIONINFO_H + +#define BUILD_TIMESTAMP "2021-02-11 12:10" +#define CLIENT_VERSION "1.3.8" + +#endif /* VERSIONINFO_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/WebSocket.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/WebSocket.h new file mode 100644 index 0000000..e9f5765 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/WebSocket.h @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2018, 2020 Wind River Systems, Inc. and others. All Rights Reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Keith Holman - initial implementation and documentation + *******************************************************************************/ + +#if !defined(WEBSOCKET_H) +#define WEBSOCKET_H + +#include "MQTTPacket.h" + +/** + * WebSocket op codes + * @{ + */ +#define WebSocket_OP_CONTINUE 0x0 /* 0000 - continue frame */ +#define WebSocket_OP_TEXT 0x1 /* 0001 - text frame */ +#define WebSocket_OP_BINARY 0x2 /* 0010 - binary frame */ +#define WebSocket_OP_CLOSE 0x8 /* 1000 - close frame */ +#define WebSocket_OP_PING 0x9 /* 1001 - ping frame */ +#define WebSocket_OP_PONG 0xA /* 1010 - pong frame */ +/** @} */ + +/** + * Various close status codes + * @{ + */ +#define WebSocket_CLOSE_NORMAL 1000 +#define WebSocket_CLOSE_GOING_AWAY 1001 +#define WebSocket_CLOSE_PROTOCOL_ERROR 1002 +#define WebSocket_CLOSE_UNKNOWN_DATA 1003 +#define WebSocket_CLOSE_RESERVED 1004 +#define WebSocket_CLOSE_NO_STATUS_CODE 1005 /* reserved: not to be used */ +#define WebSocket_CLOSE_ABNORMAL 1006 /* reserved: not to be used */ +#define WebSocket_CLOSE_BAD_DATA 1007 +#define WebSocket_CLOSE_POLICY 1008 +#define WebSocket_CLOSE_MSG_TOO_BIG 1009 +#define WebSocket_CLOSE_NO_EXTENSION 1010 +#define WebScoket_CLOSE_UNEXPECTED 1011 +#define WebSocket_CLOSE_TLS_FAIL 1015 /* reserved: not be used */ +/** @} */ + +/* closes a websocket connection */ +void WebSocket_close(networkHandles *net, int status_code, const char *reason); + +/* sends upgrade request */ +int WebSocket_connect(networkHandles *net, const char *uri); + +/* obtain data from network socket */ +int WebSocket_getch(networkHandles *net, char* c); +char *WebSocket_getdata(networkHandles *net, size_t bytes, size_t* actual_len); +size_t WebSocket_framePos(); +void WebSocket_framePosSeekTo(size_t); + +/* send data out, in websocket format only if required */ +int WebSocket_putdatas(networkHandles* net, char** buf0, size_t* buf0len, PacketBuffers* bufs); + +/* releases any resources used by the websocket system */ +void WebSocket_terminate(void); + +/* handles websocket upgrade request */ +int WebSocket_upgrade(networkHandles *net); + +/* Notify the IP address and port of the endpoint to proxy, and wait connection to endpoint */ +int WebSocket_proxy_connect( networkHandles *net, int ssl, const char *hostname); + +#endif /* WEBSOCKET_H */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/mutex_type.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/mutex_type.h new file mode 100644 index 0000000..1e4b9e5 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/mutex_type.h @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + *******************************************************************************/ +#if !defined(_MUTEX_TYPE_H_) +#define _MUTEX_TYPE_H_ + +#if defined(_WIN32) || defined(_WIN64) + #include + #define mutex_type HANDLE +#else + #include + #define mutex_type pthread_mutex_t* +#endif + +#endif /* _MUTEX_TYPE_H_ */ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/utf-8.h b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/utf-8.h new file mode 100644 index 0000000..a7a4270 --- /dev/null +++ b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/include/utf-8.h @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * https://www.eclipse.org/legal/epl-2.0/ + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(UTF8_H) +#define UTF8_H + +int UTF8_validate(int len, const char *data); +int UTF8_validateString(const char* string); + +#endif diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libAR.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libAR.a new file mode 100644 index 0000000..41d916b Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libAR.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libOpenSSL_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libOpenSSL_s.a new file mode 100644 index 0000000..ae327e0 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libOpenSSL_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libPahoMQTT_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libPahoMQTT_s.a new file mode 100644 index 0000000..d696a35 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libPahoMQTT_s.a differ diff --git a/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libar_posix_s.a b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libar_posix_s.a new file mode 100644 index 0000000..695ce87 Binary files /dev/null and b/PahoMQTT/1.3.8-rev03/PahoMQTT/V4.73.0/SG4/libar_posix_s.a differ diff --git a/README.md b/README.md index 2e94c75..de04b31 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ AR version as possible. - rev.01 - First release - Based on `OpenSSL 1.1.1g` and `paho.mqtt.c 1.3.5` - - All Library versions come with the same version as the AR they are built for, whereas `ArSim` versions have the last version + - All Library versions come with the same version as the AR they are built for, whereas `ARsim` versions have the last version number `.1`, like `4.73.1` and PC targets (with more than 128 sockets) have the last version number `.9`, like `4.73.9`. - rev.02 - Based on `OpenSSL 1.1.1g` and `paho.mqtt.c 1.3.7` @@ -55,6 +55,10 @@ AR version as possible. - New samples involving `IotMqttRegParPublish`, `IotMqttRegParSubscribe` and `GoogleIotCredentials` - Fixed issue: https://github.com/br-automation-com/paho.mqtt.c-ar/issues/4 - Fixed an issue that could lead IotMqttPublish to an unresponsive state +- rev.03 + - Based on `OpenSSL 1.1.1g` and `paho.mqtt.c 1.3.8` + - Fixed [issue #6](https://github.com/br-automation-com/paho.mqtt.c-ar/issues/6) + - Added *SendTimeout* input parameter to `IotMqttPublish` and`IotMqttRegParPublish` ## Using IotMqtt @@ -65,9 +69,9 @@ The IotMqtt library enables simple usage within IEC programs. It consists on 3 d - Publisher - Subscriber -Everytime a new connection with a MQTT broker is desired, an IotMqttClient FUB must be used. Then, depending on the pubish/subscribe needs, it is possible to associate from 0 to 50 `IotMqttPublish` or `IotMqttSubscribe` FUBs. `IotMqttRegParPublish` and `IotMqttRegParSubscribe` also count as `IotMqttPublish` or `IotMqttSubscribe` +Every time a new connection with a MQTT broker is desired, an IotMqttClient FUB must be used. Then, depending on the pubish/subscribe needs, it is possible to associate from 0 to 50 `IotMqttPublish` or `IotMqttSubscribe` FUBs. `IotMqttRegParPublish` and `IotMqttRegParSubscribe` also count as `IotMqttPublish` or `IotMqttSubscribe` -Here are some simple samples. Before running them,**it is important to change the ClientID** parameter to a customized one, since the **ClientID must be unique** in the broker. +Here are some simple samples. Before running them, **it is important to change the ClientID** parameter to a customized one, since the **ClientID must be unique** in the broker. - Publish sample: This sample shows how to connect, and publish MQTT messages to a topic @@ -133,6 +137,51 @@ Here are some simple samples. Before running them,**it is important to change th ![](images/subscribe_sample.gif) +- RegPar Publish and Subscribe samples: This sample demonstrates how to use these two Function Blocks to send a json serialized PLC structure (publish) and to receive and parse a json message to a PLC structure (subscribe). + + ``` + PROGRAM _CYCLIC + pvname := 'RegParPub:testVar'; + testVar; + + IotMqttParameters.ServerUri := 'broker.hivemq.com'; + IotMqttParameters.Port := 1883; + IotMqttParameters.ClientID := 'B&R_SimplePublishSample585'; + + IotMqttClient_0.Enable := TRUE; + IotMqttClient_0.Connect := TRUE; + IotMqttClient_0.IotMqttLink := ADR(IotMqttLink); + IotMqttClient_0.Parameters := IotMqttParameters; + IotMqttClient_0(); + + IotMqttRegParPublish_0.Enable := TRUE; + IotMqttRegParPublish_0.IotMqttLink := IotMqttClient_0.IotMqttLink; + IotMqttRegParPublish_0.Topic := ADR('B&R_TestTopic/RegParPublishSample'); + IotMqttRegParPublish_0.PvName := ADR(pvname); + IotMqttRegParPublish_0.PublishMode := IOTMQTT_PUB_MODE_TRIGGER; + IotMqttRegParPublish_0.DataFormat := IOTMQTT_VAR_JSON; + IotMqttRegParPublish_0(); + + IotMqttRegParSubscribe_0.Enable := TRUE; + IotMqttRegParSubscribe_0.IotMqttLink := IotMqttClient_0.IotMqttLink; + IotMqttRegParSubscribe_0.DataFormat := IOTMQTT_VAR_JSON; + IotMqttRegParSubscribe_0.Topic := ADR('B&R_TestTopic/RegParSubscribeSample'); + IotMqttRegParSubscribe_0.QoS := 0; + IotMqttRegParSubscribe_0.QueueSize := 50; + IotMqttRegParSubscribe_0.ReceiveBufferSize := 50000; + IotMqttRegParSubscribe_0(); + END_PROGRAM + + PROGRAM _EXIT + IotMqttClient_0(Enable := FALSE); + IotMqttRegParPublish_0(Enable := FALSE); + END_PROGRAM + ``` + + ![](images\regpar_publish_sample.gif) + + ![](images\regpar_subscribe_sample.gif) + - Library configuration: This sample shows how to change the logging behaviour and file devices that the library uses. The library works with the default parameters, making its use optional. ``` diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Main.st b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Main.st index 72dd10b..0e33b9a 100644 --- a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Main.st +++ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Main.st @@ -1,11 +1,7 @@ - -PROGRAM _INIT - pvname := 'RegParPub:testVar'; - testVar := 0; - IotMqttRegParPublish_0.SamplingTime := T#10s; -END_PROGRAM - PROGRAM _CYCLIC + pvname := 'RegParPub:testVar'; + testVar; + IotMqttParameters.ServerUri := 'test.mosquitto.org'; IotMqttParameters.Port := 1883; IotMqttParameters.ClientID := 'B&R_SimplePublishSample58225'; @@ -16,7 +12,7 @@ PROGRAM _CYCLIC IotMqttClient_0.Parameters := IotMqttParameters; IotMqttClient_0(); - //IotMqttRegParPublish_0.Enable := TRUE; + IotMqttRegParPublish_0.Enable := TRUE; IotMqttRegParPublish_0.IotMqttLink := IotMqttClient_0.IotMqttLink; IotMqttRegParPublish_0.Topic := ADR('B&R_TestTopic/RegParPublishSample_'); IotMqttRegParPublish_0.PvName := ADR(pvname); @@ -24,13 +20,13 @@ PROGRAM _CYCLIC IotMqttRegParPublish_0.DataFormat := IOTMQTT_VAR_JSON; IotMqttRegParPublish_0(); - IotMqttRegParSubscribe_0.IotMqttLink := IotMqttClient_0.IotMqttLink; -// IotMqttRegParSubscribe_0.Enable := TRUE; - IotMqttRegParSubscribe_0.PvName := ADR(pvname); - IotMqttRegParSubscribe_0.DataFormat := IOTMQTT_VAR_JSON; - IotMqttRegParSubscribe_0.Topic := ADR('B&R_TestTopic/RegParSubscribeSample_'); - IotMqttRegParSubscribe_0.QoS := 0; - IotMqttRegParSubscribe_0.QueueSize := 50; + IotMqttRegParSubscribe_0.IotMqttLink := IotMqttClient_0.IotMqttLink; + IotMqttRegParSubscribe_0.Enable := TRUE; + IotMqttRegParSubscribe_0.PvName := ADR(pvname); + IotMqttRegParSubscribe_0.DataFormat := IOTMQTT_VAR_JSON; + IotMqttRegParSubscribe_0.Topic := ADR('B&R_TestTopic/RegParSubscribeSample_'); + IotMqttRegParSubscribe_0.QoS := 0; + IotMqttRegParSubscribe_0.QueueSize := 50; IotMqttRegParSubscribe_0.ReceiveBufferSize := 50000; IotMqttRegParSubscribe_0(); END_PROGRAM diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Types.typ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Types.typ index e69de29..7876519 100644 --- a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Types.typ +++ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Types.typ @@ -0,0 +1,8 @@ + +TYPE + MyStruct_type : STRUCT + RealNum : REAL; + TextVar : STRING[80]; + Boolean : BOOL; + END_STRUCT; +END_TYPE diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Variables.var b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Variables.var index 7682111..f3c2a7d 100644 --- a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Variables.var +++ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Demos/RegParPub/Variables.var @@ -4,6 +4,6 @@ VAR pvname : STRING[80]; IotMqttLink : IoTMqttComIdentType; IotMqttParameters : IotMqttClientParType; - testVar : INT; + testVar : MyStruct_type; IotMqttRegParSubscribe_0 : IotMqttRegParSubscribe; END_VAR diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/Binary.lby b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/Binary.lby index c02ead5..56932b5 100644 --- a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/Binary.lby +++ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/Binary.lby @@ -1,6 +1,6 @@  - + Types.typ Constants.var diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/Constants.var b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/Constants.var index 5b9d560..dce1395 100644 --- a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/Constants.var +++ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/Constants.var @@ -15,6 +15,7 @@ VAR CONSTANT IOTMQTT_ERR_WRONG_QUEUE_SIZE : DINT := -10012; IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE : DINT := -10013; IOTMQTT_ERR_CONN_REFUSED : DINT := -10014; + IOTMQTT_ERR_SENDING_TIMEDOUT : DINT := -10015; END_VAR (*Warnings*) VAR CONSTANT diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/IotMqtt.fun b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/IotMqtt.fun index f9f38a8..dea6966 100644 --- a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/IotMqtt.fun +++ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/IotMqtt.fun @@ -26,7 +26,9 @@ END_FUNCTION_BLOCK VAR_INPUT IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) Send : {REDUND_UNREPLICABLE} BOOL; (*Edge sensitive. Will send a new message each time is set high*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) Buffer : {REDUND_UNREPLICABLE} UDINT; (*Pointer to data buffer*) @@ -44,6 +46,8 @@ END_FUNCTION_BLOCK VAR _Send : {REDUND_UNREPLICABLE} BOOL; _Active : {REDUND_UNREPLICABLE} BOOL; + _ErrorReset : {REDUND_UNREPLICABLE} BOOL; + _t0 : {REDUND_UNREPLICABLE} UDINT; END_VAR END_FUNCTION_BLOCK @@ -51,10 +55,12 @@ END_FUNCTION_BLOCK VAR_INPUT IotMqttLink : REFERENCE TO IoTMqttComIdentType; (*Connection to TP Configuration*) Enable : {REDUND_UNREPLICABLE} BOOL; (*Enables FUB*) + ErrorReset : {REDUND_UNREPLICABLE} BOOL; (*Reset errors on positive edge*) Update : {REDUND_UNREPLICABLE} BOOL; (*Edfe sensitive. Will update the internal values for PvName, Mode, PublishMode and SamplingTime*) Topic : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the Topic Name*) QoS : {REDUND_UNREPLICABLE} IotMqttQosEnum; (*The quality of service (QoS) assigned to the message.*) Retained : {REDUND_UNREPLICABLE} BOOL; (*Is message of type retain?*) + SendTimeout : {REDUND_UNREPLICABLE} TIME; (*If message is not delivered after this time, an error will be set in the FB (if SendTimeout > 0)*) PvName : {REDUND_UNREPLICABLE} UDINT; (*Pointer to STRING with the PV*) DataFormat : {REDUND_UNREPLICABLE} IotMqttDataFormatEnum; (*Allows choosing if variable will be serialized to Json or sent in binary form*) PublishMode : {REDUND_UNREPLICABLE} IotMqttPublishModeEnum; (*Which event or events will send the PV data?*) diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/Arm/IotMqtt.br b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/Arm/IotMqtt.br index 91f270e..4591253 100644 Binary files a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/Arm/IotMqtt.br and b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/Arm/IotMqtt.br differ diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/IotMqtt.br b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/IotMqtt.br index 377c7a8..3b07ab0 100644 Binary files a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/IotMqtt.br and b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/IotMqtt.br differ diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/IotMqtt.h b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/IotMqtt.h index cea9861..cf8def6 100644 --- a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/IotMqtt.h +++ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/IotMqtt/SG4/IotMqtt.h @@ -69,6 +69,7 @@ extern "C" #define IOTMQTT_ERR_WRONG_QUEUE_SIZE (-10012) #define IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE (-10013) #define IOTMQTT_ERR_CONN_REFUSED (-10014) + #define IOTMQTT_ERR_SENDING_TIMEDOUT (-10015) #define IOTMQTT_WRN_ALREADY_ALLOCATED (-20001) #define IOTMQTT_WRN_ALREADY_FREED (-20002) #define IOTMQTT_WRN_NO_MORE_MESSAGES (-20003) @@ -100,6 +101,7 @@ extern "C" _GLOBAL_CONST signed long IOTMQTT_ERR_WRONG_QUEUE_SIZE; _GLOBAL_CONST signed long IOTMQTT_ERR_IOT_MQTT_LINK_IN_USE; _GLOBAL_CONST signed long IOTMQTT_ERR_CONN_REFUSED; + _GLOBAL_CONST signed long IOTMQTT_ERR_SENDING_TIMEDOUT; _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_ALLOCATED; _GLOBAL_CONST signed long IOTMQTT_WRN_ALREADY_FREED; _GLOBAL_CONST signed long IOTMQTT_WRN_NO_MORE_MESSAGES; @@ -296,6 +298,7 @@ typedef struct IotMqttPublish { /* VAR_INPUT (analog) */ struct IoTMqttComIdentType* IotMqttLink; + plctime SendTimeout; unsigned long Topic; enum IotMqttQosEnum QoS; unsigned long Buffer; @@ -303,8 +306,11 @@ typedef struct IotMqttPublish /* VAR_OUTPUT (analog) */ signed long StatusID; struct IotMqttPublishInfoType Info; + /* VAR (analog) */ + unsigned long _t0; /* VAR_INPUT (digital) */ plcbit Enable; + plcbit ErrorReset; plcbit Send; plcbit Retained; /* VAR_OUTPUT (digital) */ @@ -315,6 +321,7 @@ typedef struct IotMqttPublish /* VAR (digital) */ plcbit _Send; plcbit _Active; + plcbit _ErrorReset; } IotMqttPublish_typ; typedef struct IotMqttRegParPublish @@ -323,6 +330,7 @@ typedef struct IotMqttRegParPublish struct IoTMqttComIdentType* IotMqttLink; unsigned long Topic; enum IotMqttQosEnum QoS; + plctime SendTimeout; unsigned long PvName; enum IotMqttDataFormatEnum DataFormat; enum IotMqttPublishModeEnum PublishMode; @@ -343,6 +351,7 @@ typedef struct IotMqttRegParPublish plctime _t0; /* VAR_INPUT (digital) */ plcbit Enable; + plcbit ErrorReset; plcbit Update; plcbit Retained; plcbit Trigger; diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/Package.pkg b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/Package.pkg index 3243fdf..83a8087 100644 --- a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/Package.pkg +++ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Logical/Libraries/Package.pkg @@ -16,6 +16,6 @@ standard brsystem AsIODiag - IotMqtt + IotMqtt \ No newline at end of file diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Physical/X20CP0482/X20CP0482/Cpu.sw b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Physical/X20CP0482/X20CP0482/Cpu.sw index 5bbd797..293f466 100644 --- a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Physical/X20CP0482/X20CP0482/Cpu.sw +++ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Physical/X20CP0482/X20CP0482/Cpu.sw @@ -49,6 +49,5 @@ - \ No newline at end of file diff --git a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Physical/X20CP1586/X20CP1586/Cpu.sw b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Physical/X20CP1586/X20CP1586/Cpu.sw index 5bbd797..293f466 100644 --- a/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Physical/X20CP1586/X20CP1586/Cpu.sw +++ b/Samples/IotMqttSamples/SampleProject/IotMqttDemo/Physical/X20CP1586/X20CP1586/Cpu.sw @@ -49,6 +49,5 @@ - \ No newline at end of file diff --git a/images/regpar_publish_sample.gif b/images/regpar_publish_sample.gif new file mode 100644 index 0000000..50bea97 Binary files /dev/null and b/images/regpar_publish_sample.gif differ diff --git a/images/regpar_subscribe_sample.gif b/images/regpar_subscribe_sample.gif new file mode 100644 index 0000000..b36b0e9 Binary files /dev/null and b/images/regpar_subscribe_sample.gif differ