1 /******************************************************************************* 2 * Copyright (c) 2009, 2020 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 v2.0 6 * and Eclipse Distribution License v1.0 which accompany this distribution. 7 * 8 * The Eclipse Public License is available at 9 * https://www.eclipse.org/legal/epl-2.0/ 10 * and the Eclipse Distribution License is available at 11 * http://www.eclipse.org/org/documents/edl-v10.php. 12 * 13 * Contributors: 14 * Ian Craggs - initial API and implementation and/or initial documentation 15 * Ian Craggs, Allan Stockdill-Mander - SSL updates 16 * Ian Craggs - MQTT 3.1.1 support 17 * Ian Craggs - big endian Linux reversed definition 18 * Ian Craggs - MQTT 5.0 support 19 *******************************************************************************/ 20 21 #if !defined(MQTTPACKET_H) 22 #define MQTTPACKET_H 23 24 #include "Socket.h" 25 #if defined(OPENSSL) || defined(MBEDTLS) 26 #include "SSLSocket.h" 27 #endif 28 #include "LinkedList.h" 29 #include "Clients.h" 30 31 #if !defined(IOT_CONNECT) && !defined(__LITEOS__) && !defined(IOT_LITEOS_ADAPT) 32 typedef unsigned int bool; 33 #endif 34 typedef void* (*pf)(int, unsigned char, char*, size_t); 35 36 #include "MQTTProperties.h" 37 #include "MQTTReasonCodes.h" 38 39 enum errors 40 { 41 MQTTPACKET_BAD = -4, 42 MQTTPACKET_BUFFER_TOO_SHORT = -2, 43 MQTTPACKET_READ_ERROR = -1, 44 MQTTPACKET_READ_COMPLETE 45 }; 46 47 48 enum msgTypes 49 { 50 CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, 51 PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, 52 PINGREQ, PINGRESP, DISCONNECT, AUTH 53 }; 54 55 #if defined(__linux__) 56 #include <endian.h> 57 #if __BYTE_ORDER == __BIG_ENDIAN 58 #define REVERSED 1 59 #endif 60 #endif 61 62 /** 63 * Bitfields for the MQTT header byte. 64 */ 65 typedef union 66 { 67 /*unsigned*/ char byte; /**< the whole byte */ 68 #if defined(REVERSED) 69 struct 70 { 71 unsigned int type : 4; /**< message type nibble */ 72 bool dup : 1; /**< DUP flag bit */ 73 unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ 74 bool retain : 1; /**< retained flag bit */ 75 } bits; 76 #else 77 struct 78 { 79 bool retain : 1; /**< retained flag bit */ 80 unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ 81 bool dup : 1; /**< DUP flag bit */ 82 unsigned int type : 4; /**< message type nibble */ 83 } bits; 84 #endif 85 } Header; 86 87 88 /** 89 * Data for a connect packet. 90 */ 91 typedef struct 92 { 93 Header header; /**< MQTT header byte */ 94 union 95 { 96 unsigned char all; /**< all connect flags */ 97 #if defined(REVERSED) 98 struct 99 { 100 bool username : 1; /**< 3.1 user name */ 101 bool password : 1; /**< 3.1 password */ 102 bool willRetain : 1; /**< will retain setting */ 103 unsigned int willQoS : 2; /**< will QoS value */ 104 bool will : 1; /**< will flag */ 105 bool cleanstart : 1; /**< cleansession flag */ 106 int : 1; /**< unused */ 107 } bits; 108 #else 109 struct 110 { 111 int : 1; /**< unused */ 112 bool cleanstart : 1; /**< cleansession flag */ 113 bool will : 1; /**< will flag */ 114 unsigned int willQoS : 2; /**< will QoS value */ 115 bool willRetain : 1; /**< will retain setting */ 116 bool password : 1; /**< 3.1 password */ 117 bool username : 1; /**< 3.1 user name */ 118 } bits; 119 #endif 120 } flags; /**< connect flags byte */ 121 122 char *Protocol, /**< MQTT protocol name */ 123 *clientID, /**< string client id */ 124 *willTopic, /**< will topic */ 125 *willMsg; /**< will payload */ 126 127 int keepAliveTimer; /**< keepalive timeout value in seconds */ 128 unsigned char version; /**< MQTT version number */ 129 } Connect; 130 131 132 /** 133 * Data for a connack packet. 134 */ 135 typedef struct 136 { 137 Header header; /**< MQTT header byte */ 138 union 139 { 140 unsigned char all; /**< all connack flags */ 141 #if defined(REVERSED) 142 struct 143 { 144 unsigned int reserved : 7; /**< message type nibble */ 145 bool sessionPresent : 1; /**< was a session found on the server? */ 146 } bits; 147 #else 148 struct 149 { 150 bool sessionPresent : 1; /**< was a session found on the server? */ 151 unsigned int reserved : 7; /**< message type nibble */ 152 } bits; 153 #endif 154 } flags; /**< connack flags byte */ 155 unsigned char rc; /**< connack reason code */ 156 unsigned int MQTTVersion; /**< the version of MQTT */ 157 MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ 158 } Connack; 159 160 161 /** 162 * Data for a packet with header only. 163 */ 164 typedef struct 165 { 166 Header header; /**< MQTT header byte */ 167 } MQTTPacket; 168 169 170 /** 171 * Data for a suback packet. 172 */ 173 typedef struct 174 { 175 Header header; /**< MQTT header byte */ 176 int msgId; /**< MQTT message id */ 177 int MQTTVersion; /**< the version of MQTT */ 178 MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ 179 List* qoss; /**< list of granted QoSs (MQTT 3/4) / reason codes (MQTT 5) */ 180 } Suback; 181 182 183 /** 184 * Data for an MQTT V5 unsuback packet. 185 */ 186 typedef struct 187 { 188 Header header; /**< MQTT header byte */ 189 int msgId; /**< MQTT message id */ 190 int MQTTVersion; /**< the version of MQTT */ 191 MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ 192 List* reasonCodes; /**< list of reason codes */ 193 } Unsuback; 194 195 196 /** 197 * Data for a publish packet. 198 */ 199 typedef struct 200 { 201 Header header; /**< MQTT header byte */ 202 char* topic; /**< topic string */ 203 int topiclen; 204 int msgId; /**< MQTT message id */ 205 char* payload; /**< binary payload, length delimited */ 206 int payloadlen; /**< payload length */ 207 int MQTTVersion; /**< the version of MQTT */ 208 MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ 209 uint8_t mask[4]; /**< the websockets mask the payload is masked with, if any */ 210 } Publish; 211 212 213 /** 214 * Data for one of the ack packets. 215 */ 216 typedef struct 217 { 218 Header header; /**< MQTT header byte */ 219 int msgId; /**< MQTT message id */ 220 unsigned char rc; /**< MQTT 5 reason code */ 221 int MQTTVersion; /**< the version of MQTT */ 222 MQTTProperties properties; /**< MQTT 5.0 properties. Not used for MQTT < 5.0 */ 223 } Ack; 224 225 typedef Ack Puback; 226 typedef Ack Pubrec; 227 typedef Ack Pubrel; 228 typedef Ack Pubcomp; 229 230 int MQTTPacket_encode(char* buf, size_t length); 231 int MQTTPacket_decode(networkHandles* net, size_t* value); 232 int readInt(char** pptr); 233 char* readUTF(char** pptr, char* enddata); 234 unsigned char readChar(char** pptr); 235 void writeChar(char** pptr, char c); 236 void writeInt(char** pptr, int anInt); 237 void writeUTF(char** pptr, const char* string); 238 void writeData(char** pptr, const void* data, int datalen); 239 240 const char* MQTTPacket_name(int ptype); 241 242 void* MQTTPacket_Factory(int MQTTVersion, networkHandles* net, int* error); 243 int MQTTPacket_send(networkHandles* net, Header header, char* buffer, size_t buflen, int free, int MQTTVersion); 244 int MQTTPacket_sends(networkHandles* net, Header header, PacketBuffers* buffers, int MQTTVersion); 245 246 void* MQTTPacket_header_only(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); 247 int MQTTPacket_send_disconnect(Clients* client, enum MQTTReasonCodes reason, MQTTProperties* props); 248 249 void* MQTTPacket_publish(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); 250 void MQTTPacket_freePublish(Publish* pack); 251 int MQTTPacket_send_publish(Publish* pack, int dup, int qos, int retained, networkHandles* net, const char* clientID); 252 int MQTTPacket_send_puback(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); 253 void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t datalen); 254 255 void MQTTPacket_freeAck(Ack* pack); 256 void MQTTPacket_freeSuback(Suback* pack); 257 void MQTTPacket_freeUnsuback(Unsuback* pack); 258 int MQTTPacket_send_pubrec(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); 259 int MQTTPacket_send_pubrel(int MQTTVersion, int msgid, int dup, networkHandles* net, const char* clientID); 260 int MQTTPacket_send_pubcomp(int MQTTVersion, int msgid, networkHandles* net, const char* clientID); 261 262 void MQTTPacket_free_packet(MQTTPacket* pack); 263 264 void writeInt4(char** pptr, int anInt); 265 int readInt4(char** pptr); 266 void writeMQTTLenString(char** pptr, MQTTLenString lenstring); 267 int MQTTLenStringRead(MQTTLenString* lenstring, char** pptr, char* enddata); 268 int MQTTPacket_VBIlen(int rem_len); 269 int MQTTPacket_decodeBuf(char* buf, unsigned int* value); 270 271 #include "MQTTPacketOut.h" 272 273 #endif /* MQTTPACKET_H */ 274