1 /******************************************************************************* 2 * Copyright (c) 2009, 2022 IBM Corp. and Ian Craggs 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 - add SSL support 16 * Ian Craggs - fix for bug 413429 - connectionLost not called 17 * Ian Craggs - change will payload to binary 18 * Ian Craggs - password to binary 19 * Ian Craggs - MQTT 5 support 20 *******************************************************************************/ 21 22 #if !defined(CLIENTS_H) 23 #define CLIENTS_H 24 25 #include <stdint.h> 26 #include "MQTTTime.h" 27 #if defined(_WIN32) || defined(_WIN64) 28 #include <winsock2.h> 29 #endif 30 #if defined(OPENSSL) 31 #include <openssl/ssl.h> 32 #endif 33 34 #if defined(MBEDTLS) 35 #include <mbedtls/ctr_drbg.h> 36 #include <mbedtls/entropy.h> 37 #include <mbedtls/ssl.h> 38 #if defined(MBEDTLS_USE_CRT) 39 #include <mbedtls/x509_crt.h> 40 #endif /* MBEDTLS_USE_CRT */ 41 #endif /* MBEDTLS */ 42 43 #include "MQTTClient.h" 44 #include "LinkedList.h" 45 #include "MQTTClientPersistence.h" 46 #include "Socket.h" 47 48 /** 49 * Stored publication data to minimize copying 50 */ 51 typedef struct 52 { 53 char *topic; 54 int topiclen; 55 char* payload; 56 int payloadlen; 57 int refcount; 58 uint8_t mask[4]; 59 } Publications; 60 61 /** 62 * Client publication message data 63 */ 64 typedef struct 65 { 66 int qos; 67 int retain; 68 int msgid; 69 int MQTTVersion; 70 MQTTProperties properties; 71 Publications *publish; 72 START_TIME_TYPE lastTouch; /**> used for retry and expiry */ 73 char nextMessageType; /**> PUBREC, PUBREL, PUBCOMP */ 74 int len; /**> length of the whole structure+data */ 75 #if defined(IOT_CONNECT) || defined(IOT_LITEOS_ADAPT) 76 int retryTime; 77 #endif 78 } Messages; 79 80 /** 81 * Client will message data 82 */ 83 typedef struct 84 { 85 char *topic; 86 int payloadlen; 87 void *payload; 88 int retained; 89 int qos; 90 } willMessages; 91 92 #if defined(MBEDTLS) 93 typedef struct 94 { 95 mbedtls_ssl_config conf; 96 mbedtls_entropy_context entropy; 97 mbedtls_ctr_drbg_context ctr_drbg; 98 #if defined(MBEDTLS_USE_CRT) 99 mbedtls_x509_crt cacert; 100 mbedtls_x509_crt clicert; 101 mbedtls_pk_context pkey; 102 #endif /* MBEDTLS_USE_CRT */ 103 } SSL_CTX; 104 105 typedef mbedtls_ssl_context SSL; 106 typedef mbedtls_ssl_session SSL_SESSION; 107 #endif /* MBEDTLS */ 108 109 typedef struct 110 { 111 SOCKET socket; 112 START_TIME_TYPE lastSent; 113 START_TIME_TYPE lastReceived; 114 START_TIME_TYPE lastPing; 115 #if defined(OPENSSL) || defined(MBEDTLS) 116 SSL* ssl; 117 SSL_CTX* ctx; 118 char *https_proxy; 119 char *https_proxy_auth; 120 #endif 121 char *http_proxy; 122 char *http_proxy_auth; 123 int websocket; /**< socket has been upgraded to use web sockets */ 124 char *websocket_key; 125 const MQTTClient_nameValue* httpHeaders; 126 } networkHandles; 127 128 129 /* connection states */ 130 /** no connection in progress, see connected value */ 131 #define NOT_IN_PROGRESS 0x0 132 /** TCP connection in progress */ 133 #define TCP_IN_PROGRESS 0x1 134 /** SSL connection in progress */ 135 #define SSL_IN_PROGRESS 0x2 136 /** Websocket connection in progress */ 137 #define WEBSOCKET_IN_PROGRESS 0x3 138 /** TCP completed, waiting for MQTT ACK */ 139 #define WAIT_FOR_CONNACK 0x4 140 /** Proxy connection in progress */ 141 #define PROXY_CONNECT_IN_PROGRESS 0x5 142 /** Disconnecting */ 143 #define DISCONNECTING -2 144 145 /** 146 * Data related to one client 147 */ 148 typedef struct 149 { 150 char* clientID; /**< the string id of the client */ 151 const char* username; /**< MQTT v3.1 user name */ 152 int passwordlen; /**< MQTT password length */ 153 const void* password; /**< MQTT v3.1 binary password */ 154 unsigned int cleansession : 1; /**< MQTT V3 clean session flag */ 155 unsigned int cleanstart : 1; /**< MQTT V5 clean start flag */ 156 unsigned int connected : 1; /**< whether it is currently connected */ 157 unsigned int good : 1; /**< if we have an error on the socket we turn this off */ 158 unsigned int ping_outstanding : 1; 159 unsigned int ping_due : 1; /**< we couldn't send a ping so we should send one when we can */ 160 signed int connect_state : 4; 161 START_TIME_TYPE ping_due_time; /**< the time at which the ping should have been sent (ping_due) */ 162 networkHandles net; /**< network info for this client */ 163 int msgID; /**< the MQTT message id */ 164 int keepAliveInterval; /**< the MQTT keep alive interval */ 165 int retryInterval; /**< the MQTT retry interval for QoS > 0 */ 166 int maxInflightMessages; /**< the max number of inflight outbound messages we allow */ 167 willMessages* will; /**< the MQTT will message, if any */ 168 List* inboundMsgs; /**< inbound in flight messages */ 169 List* outboundMsgs; /**< outbound in flight messages */ 170 int connect_count; /**< the number of outbound messages on reconnect - to ensure we send them all */ 171 int connect_sent; /**< the current number of outbound messages on reconnect that we've sent */ 172 List* messageQueue; /**< inbound complete but undelivered messages */ 173 List* outboundQueue; /**< outbound queued messages */ 174 #if defined(IOT_CONNECT) || defined(IOT_LITEOS_ADAPT) 175 int retryMsgs; /**< retry end but not waitForCompletion*/ 176 #endif 177 unsigned int qentry_seqno; 178 void* phandle; /**< the persistence handle */ 179 MQTTClient_persistence* persistence; /**< a persistence implementation */ 180 MQTTPersistence_beforeWrite* beforeWrite; /**< persistence write callback */ 181 MQTTPersistence_afterRead* afterRead; /**< persistence read callback */ 182 void* beforeWrite_context; /**< context to be used with the persistence beforeWrite callbacks */ 183 void* afterRead_context; /**< context to be used with the persistence afterRead callback */ 184 void* context; /**< calling context - used when calling disconnect_internal */ 185 int MQTTVersion; /**< the version of MQTT being used, 3, 4 or 5 */ 186 int sessionExpiry; /**< MQTT 5 session expiry */ 187 char* httpProxy; /**< HTTP proxy */ 188 char* httpsProxy; /**< HTTPS proxy */ 189 #if defined(OPENSSL) || defined(MBEDTLS) 190 MQTTClient_SSLOptions *sslopts; /**< the SSL/TLS connect options */ 191 SSL_SESSION* session; /**< SSL session pointer for fast handhake */ 192 #endif 193 } Clients; 194 195 int clientIDCompare(void* a, void* b); 196 int clientSocketCompare(void* a, void* b); 197 198 /** 199 * Configuration data related to all clients 200 */ 201 typedef struct 202 { 203 const char* version; 204 List* clients; 205 } ClientStates; 206 207 #endif 208