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(WIN32_DLL) || defined(WIN64_DLL) 23 #define DLLImport __declspec(dllimport) 24 #define DLLExport __declspec(dllexport) 25 #elif defined(LINUX_SO) 26 #define DLLImport extern 27 #define DLLExport __attribute__ ((visibility ("default"))) 28 #else 29 #define DLLImport 30 #define DLLExport 31 #endif 32 33 #include "liteOS/MQTTLiteOS.h" 34 35 #include "MQTTPacket.h" 36 37 #define MAX_PACKET_ID 65535 /* according to the MQTT specification - do not change! */ 38 39 #if !defined(MAX_MESSAGE_HANDLERS) 40 #define MAX_MESSAGE_HANDLERS 5 /* redefinable - how many subscriptions do you want? */ 41 #endif 42 43 enum QoS { QOS0, QOS1, QOS2, SUBFAIL = 0x80 }; 44 45 /* all failure return codes must be negative */ 46 enum returnCode { BUFFER_OVERFLOW = -2, FAILURE = -1, SUCCESS = 0 }; 47 48 /* The Platform specific header must define the Network and Timer structures and functions 49 * which operate on them. 50 * 51 typedef struct Network 52 { 53 int (*mqttread)(Network*, unsigned char* read_buffer, int, int); 54 int (*mqttwrite)(Network*, unsigned char* send_buffer, int, int); 55 } Network;* / 56 57 /* The Timer structure must be defined in the platform specific header, 58 * and have the following functions to operate on it. */ 59 extern void TimerInit(Timer* timer); 60 extern char TimerIsExpired(Timer* timer); 61 extern void TimerCountdownMS(Timer* timer, unsigned int); 62 extern void TimerCountdown(Timer* timer, unsigned int); 63 extern int TimerLeftMS(Timer* timer); 64 65 typedef struct MQTTMessage { 66 enum QoS qos; 67 unsigned char retained; 68 unsigned char dup; 69 unsigned short id; 70 void *payload; 71 size_t payloadlen; 72 } MQTTMessage; 73 74 typedef struct MessageData { 75 MQTTMessage* message; 76 MQTTString* topicName; 77 } MessageData; 78 79 typedef struct MQTTConnackData { 80 unsigned char rc; 81 unsigned char sessionPresent; 82 } MQTTConnackData; 83 84 typedef struct MQTTSubackData { 85 enum QoS grantedQoS; 86 } MQTTSubackData; 87 88 typedef void (*messageHandler)(MessageData*); 89 90 typedef struct MQTTClient { 91 unsigned int next_packetid, 92 command_timeout_ms; 93 size_t buf_size, 94 readbuf_size; 95 unsigned char *buf, 96 *readbuf; 97 unsigned int keepAliveInterval; 98 char ping_outstanding; 99 int isconnected; 100 int cleansession; 101 102 struct MessageHandlers { 103 const char* topicFilter; 104 void (*fp) (MessageData*); 105 } messageHandlers[MAX_MESSAGE_HANDLERS]; /* Message handlers are indexed by subscription topic */ 106 107 void (*defaultMessageHandler) (MessageData*); 108 109 Network* ipstack; 110 Timer last_sent, last_received; 111 #if defined(MQTT_TASK) 112 Mutex mutex; 113 Thread thread; 114 #endif 115 } MQTTClient; 116 117 #define DefaultClient {0, 0, 0, 0, NULL, NULL, 0, 0, 0} 118 119 120 /** 121 * Create an MQTT client object 122 * @param client 123 * @param network 124 * @param command_timeout_ms 125 * @param 126 */ 127 DLLExport void MQTTClientInit(MQTTClient* client, Network* network, unsigned int command_timeout_ms, 128 unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size); 129 130 /** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack 131 * The nework object must be connected to the network endpoint before calling this 132 * @param options - connect options 133 * @return success code 134 */ 135 DLLExport int MQTTConnectWithResults(MQTTClient* client, MQTTPacket_connectData* options, 136 MQTTConnackData* data); 137 138 /** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack 139 * The nework object must be connected to the network endpoint before calling this 140 * @param options - connect options 141 * @return success code 142 */ 143 DLLExport int MQTTConnect(MQTTClient* client, MQTTPacket_connectData* options); 144 145 /** MQTT Publish - send an MQTT publish packet and wait for all acks to complete for all QoSs 146 * @param client - the client object to use 147 * @param topic - the topic to publish to 148 * @param message - the message to send 149 * @return success code 150 */ 151 DLLExport int MQTTPublish(MQTTClient* client, const char*, MQTTMessage*); 152 153 /** MQTT SetMessageHandler - set or remove a per topic message handler 154 * @param client - the client object to use 155 * @param topicFilter - the topic filter set the message handler for 156 * @param messageHandler - pointer to the message handler function or NULL to remove 157 * @return success code 158 */ 159 DLLExport int MQTTSetMessageHandler(MQTTClient* c, const char* topicFilter, messageHandler messageHandler); 160 161 /** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning. 162 * @param client - the client object to use 163 * @param topicFilter - the topic filter to subscribe to 164 * @param message - the message to send 165 * @return success code 166 */ 167 DLLExport int MQTTSubscribe(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler); 168 169 /** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning. 170 * @param client - the client object to use 171 * @param topicFilter - the topic filter to subscribe to 172 * @param message - the message to send 173 * @param data - suback granted QoS returned 174 * @return success code 175 */ 176 DLLExport int MQTTSubscribeWithResults(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler, 177 MQTTSubackData* data); 178 179 /** MQTT Subscribe - send an MQTT unsubscribe packet and wait for unsuback before returning. 180 * @param client - the client object to use 181 * @param topicFilter - the topic filter to unsubscribe from 182 * @return success code 183 */ 184 DLLExport int MQTTUnsubscribe(MQTTClient* client, const char* topicFilter); 185 186 /** MQTT Disconnect - send an MQTT disconnect packet and close the connection 187 * @param client - the client object to use 188 * @return success code 189 */ 190 DLLExport int MQTTDisconnect(MQTTClient* client); 191 192 /** MQTT Yield - MQTT background 193 * @param client - the client object to use 194 * @param time - the time, in milliseconds, to yield for 195 * @return success code 196 */ 197 DLLExport int MQTTYield(MQTTClient* client, int time); 198 199 /** MQTT isConnected 200 * @param client - the client object to use 201 * @return truth value indicating whether the client is connected to the server 202 */ 203 DLLExport int MQTTIsConnected(MQTTClient* client); 204 205 #if defined(MQTT_TASK) 206 /** MQTT start background thread for a client. After this, MQTTYield should not be called. 207 * @param client - the client object to use 208 * @return success code 209 */ 210 DLLExport int MQTTStartTask(MQTTClient* client); 211 #endif 212 213 #endif 214