1 /******************************************************************************* 2 * Copyright (c) 2014, 2017 IBM Corp. 3 * 4 * All rights reserved. This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License v1.0 6 * and Eclipse Distribution License v1.0 which accompany this distribution. 7 * 8 * The Eclipse Public License is available at 9 * http://www.eclipse.org/legal/epl-v10.html 10 * and the Eclipse Distribution License is available at 11 * http://www.eclipse.org/org/documents/edl-v10.php. 12 * 13 * Contributors: 14 * Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation 15 * Ian Craggs - documentation and platform specific header 16 * Ian Craggs - add setMessageHandler function 17 *******************************************************************************/ 18 19 #if !defined(MQTT_CLIENT_H) 20 #define MQTT_CLIENT_H 21 22 #if defined(__cplusplus) 23 extern "C" { 24 #endif 25 26 #if defined(WIN32_DLL) || defined(WIN64_DLL) 27 #define DLLImport __declspec(dllimport) 28 #define DLLExport __declspec(dllexport) 29 #elif defined(LINUX_SO) 30 #define DLLImport extern 31 #define DLLExport __attribute__ ((visibility ("default"))) 32 #else 33 #define DLLImport 34 #define DLLExport 35 #endif 36 37 #include "MQTTPacket.h" 38 #include "MQTTLinux.h" 39 40 #if defined(MQTTCLIENT_PLATFORM_HEADER) 41 /* The following sequence of macros converts the MQTTCLIENT_PLATFORM_HEADER value 42 * into a string constant suitable for use with include. 43 */ 44 #define xstr(s) str(s) 45 #define str(s) #s 46 #include xstr(MQTTCLIENT_PLATFORM_HEADER) 47 #endif 48 49 #define MAX_PACKET_ID 65535 /* according to the MQTT specification - do not change! */ 50 51 #if !defined(MAX_MESSAGE_HANDLERS) 52 #define MAX_MESSAGE_HANDLERS 5 /* redefinable - how many subscriptions do you want? */ 53 #endif 54 55 enum QoS { QOS0, QOS1, QOS2, SUBFAIL=0x80 }; 56 57 /* all failure return codes must be negative */ 58 enum returnCode { BUFFER_OVERFLOW = -2, FAILURE = -1, SUCCESS = 0 }; 59 60 /* The Platform specific header must define the Network and Timer structures and functions 61 * which operate on them. 62 * 63 typedef struct Network 64 { 65 int (*mqttread)(Network*, unsigned char* read_buffer, int, int); 66 int (*mqttwrite)(Network*, unsigned char* send_buffer, int, int); 67 } Network;*/ 68 69 /* The Timer structure must be defined in the platform specific header, 70 * and have the following functions to operate on it. */ 71 extern void TimerInit(Timer*); 72 extern char TimerIsExpired(Timer*); 73 extern void TimerCountdownMS(Timer*, unsigned int); 74 extern void TimerCountdown(Timer*, unsigned int); 75 extern int TimerLeftMS(Timer*); 76 77 typedef struct MQTTMessage 78 { 79 enum QoS qos; 80 unsigned char retained; 81 unsigned char dup; 82 unsigned short id; 83 void *payload; 84 size_t payloadlen; 85 } MQTTMessage; 86 87 typedef struct MessageData 88 { 89 MQTTMessage* message; 90 MQTTString* topicName; 91 } MessageData; 92 93 typedef struct MQTTConnackData 94 { 95 unsigned char rc; 96 unsigned char sessionPresent; 97 } MQTTConnackData; 98 99 typedef struct MQTTSubackData 100 { 101 enum QoS grantedQoS; 102 } MQTTSubackData; 103 104 typedef void (*messageHandler)(MessageData*); 105 106 typedef struct MQTTClient 107 { 108 unsigned int next_packetid, 109 command_timeout_ms; 110 size_t buf_size, 111 readbuf_size; 112 unsigned char *buf, 113 *readbuf; 114 unsigned int keepAliveInterval; 115 char ping_outstanding; 116 int isconnected; 117 int cleansession; 118 119 struct MessageHandlers 120 { 121 const char* topicFilter; 122 void (*fp) (MessageData*); 123 } messageHandlers[MAX_MESSAGE_HANDLERS]; /* Message handlers are indexed by subscription topic */ 124 125 void (*defaultMessageHandler) (MessageData*); 126 127 Network* ipstack; 128 Timer last_sent, last_received; 129 #if defined(MQTT_TASK) 130 Mutex mutex; 131 Thread thread; 132 #endif 133 } MQTTClient; 134 135 #define DefaultClient {0, 0, 0, 0, NULL, NULL, 0, 0, 0} 136 137 138 /** 139 * Create an MQTT client object 140 * @param client 141 * @param network 142 * @param command_timeout_ms 143 * @param 144 */ 145 DLLExport void MQTTClientInit(MQTTClient* client, Network* network, unsigned int command_timeout_ms, 146 unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size); 147 148 /** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack 149 * The nework object must be connected to the network endpoint before calling this 150 * @param options - connect options 151 * @return success code 152 */ 153 DLLExport int MQTTConnectWithResults(MQTTClient* client, MQTTPacket_connectData* options, 154 MQTTConnackData* data); 155 156 /** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack 157 * The nework object must be connected to the network endpoint before calling this 158 * @param options - connect options 159 * @return success code 160 */ 161 DLLExport int MQTTConnect(MQTTClient* client, MQTTPacket_connectData* options); 162 163 /** MQTT Publish - send an MQTT publish packet and wait for all acks to complete for all QoSs 164 * @param client - the client object to use 165 * @param topic - the topic to publish to 166 * @param message - the message to send 167 * @return success code 168 */ 169 DLLExport int MQTTPublish(MQTTClient* client, const char*, MQTTMessage*); 170 171 /** MQTT SetMessageHandler - set or remove a per topic message handler 172 * @param client - the client object to use 173 * @param topicFilter - the topic filter set the message handler for 174 * @param messageHandler - pointer to the message handler function or NULL to remove 175 * @return success code 176 */ 177 DLLExport int MQTTSetMessageHandler(MQTTClient* c, const char* topicFilter, messageHandler messageHandler); 178 179 /** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning. 180 * @param client - the client object to use 181 * @param topicFilter - the topic filter to subscribe to 182 * @param message - the message to send 183 * @return success code 184 */ 185 DLLExport int MQTTSubscribe(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler); 186 187 /** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning. 188 * @param client - the client object to use 189 * @param topicFilter - the topic filter to subscribe to 190 * @param message - the message to send 191 * @param data - suback granted QoS returned 192 * @return success code 193 */ 194 DLLExport int MQTTSubscribeWithResults(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler, MQTTSubackData* data); 195 196 /** MQTT Subscribe - send an MQTT unsubscribe packet and wait for unsuback before returning. 197 * @param client - the client object to use 198 * @param topicFilter - the topic filter to unsubscribe from 199 * @return success code 200 */ 201 DLLExport int MQTTUnsubscribe(MQTTClient* client, const char* topicFilter); 202 203 /** MQTT Disconnect - send an MQTT disconnect packet and close the connection 204 * @param client - the client object to use 205 * @return success code 206 */ 207 DLLExport int MQTTDisconnect(MQTTClient* client); 208 209 /** MQTT Yield - MQTT background 210 * @param client - the client object to use 211 * @param time - the time, in milliseconds, to yield for 212 * @return success code 213 */ 214 DLLExport int MQTTYield(MQTTClient* client, int time); 215 216 /** MQTT isConnected 217 * @param client - the client object to use 218 * @return truth value indicating whether the client is connected to the server 219 */ 220 DLLExport int MQTTIsConnected(MQTTClient* client); 221 222 #if defined(MQTT_TASK) 223 /** MQTT start background thread for a client. After this, MQTTYield should not be called. 224 * @param client - the client object to use 225 * @return success code 226 */ 227 DLLExport int MQTTStartTask(MQTTClient* client); 228 #endif 229 230 #if defined(__cplusplus) 231 } 232 #endif 233 234 #endif 235