V.06 11/3
Dependencies: FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts
Fork of ATT_AWS_IoT_demo by
MQTTConnectClient.cpp
00001 /******************************************************************************* 00002 * Copyright (c) 2014 IBM Corp. 00003 * 00004 * All rights reserved. This program and the accompanying materials 00005 * are made available under the terms of the Eclipse Public License v1.0 00006 * and Eclipse Distribution License v1.0 which accompany this distribution. 00007 * 00008 * The Eclipse Public License is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * and the Eclipse Distribution License is available at 00011 * http://www.eclipse.org/org/documents/edl-v10.php. 00012 * 00013 * Contributors: 00014 * Ian Craggs - initial API and implementation and/or initial documentation 00015 *******************************************************************************/ 00016 00017 #include "MQTTPacket.h" 00018 #include "StackTrace.h" 00019 00020 #include <string.h> 00021 00022 /** 00023 * Determines the length of the MQTT connect packet that would be produced using the supplied connect options. 00024 * @param options the options to be used to build the connect packet 00025 * @param the length of buffer needed to contain the serialized version of the packet 00026 * @return MQTTReturnCode indicating function execution status 00027 */ 00028 size_t MQTTSerialize_GetConnectLength(MQTTPacket_connectData *options) { 00029 size_t len = 0; 00030 FUNC_ENTRY; 00031 00032 /* variable depending on MQTT or MQIsdp */ 00033 if(3 == options->MQTTVersion) { 00034 len = 12; 00035 } else if(4 == options->MQTTVersion) { 00036 len = 10; 00037 } 00038 00039 len += MQTTstrlen(options->clientID) + 2; 00040 00041 if(options->willFlag) { 00042 len += MQTTstrlen(options->will.topicName) + 2 + MQTTstrlen(options->will.message) + 2; 00043 } 00044 00045 if(options->username.cstring || options->username.lenstring.data) { 00046 len += MQTTstrlen(options->username) + 2; 00047 } 00048 00049 if(options->password.cstring || options->password.lenstring.data) { 00050 len += MQTTstrlen(options->password) + 2; 00051 } 00052 00053 FUNC_EXIT_RC(len); 00054 return len; 00055 } 00056 00057 /** 00058 * Serializes the connect options into the buffer. 00059 * @param buf the buffer into which the packet will be serialized 00060 * @param len the length in bytes of the supplied buffer 00061 * @param options the options to be used to build the connect packet 00062 * @param serialized length 00063 * @return MQTTReturnCode indicating function execution status 00064 */ 00065 MQTTReturnCode MQTTSerialize_connect(unsigned char *buf, size_t buflen, 00066 MQTTPacket_connectData *options, 00067 uint32_t *serialized_len) { 00068 unsigned char *ptr = buf; 00069 MQTTHeader header = {0}; 00070 MQTTConnectFlags flags = {0}; 00071 size_t len = 0; 00072 MQTTReturnCode rc = MQTTPacket_InitHeader(&header, CONNECT, QOS0, 0, 0); 00073 00074 FUNC_ENTRY; 00075 if(NULL == buf || NULL == options || NULL == serialized_len) { 00076 FUNC_EXIT_RC(MQTT_NULL_VALUE_ERROR); 00077 return MQTT_NULL_VALUE_ERROR; 00078 } 00079 00080 len = MQTTSerialize_GetConnectLength(options); 00081 if(MQTTPacket_len(len) > buflen) { 00082 FUNC_EXIT_RC(MQTTPACKET_BUFFER_TOO_SHORT); 00083 return MQTTPACKET_BUFFER_TOO_SHORT; 00084 } 00085 00086 if(SUCCESS != rc) { 00087 FUNC_EXIT_RC(rc); 00088 return rc; 00089 } 00090 00091 writeChar(&ptr, header.byte); /* write header */ 00092 00093 ptr += MQTTPacket_encode(ptr, len); /* write remaining length */ 00094 00095 if(4 == options->MQTTVersion) { 00096 writeCString(&ptr, "MQTT"); 00097 writeChar(&ptr, (char) 4); 00098 } else { 00099 writeCString(&ptr, "MQIsdp"); 00100 writeChar(&ptr, (char) 3); 00101 } 00102 00103 flags.all = 0; 00104 flags.bits.cleansession = (options->cleansession) ? 1 : 0; 00105 flags.bits.will = (options->willFlag) ? 1 : 0; 00106 if(flags.bits.will) { 00107 flags.bits.willQoS = options->will.qos; 00108 flags.bits.willRetain = (options->will.retained) ? 1 : 0; 00109 } 00110 00111 if(options->username.cstring || options->username.lenstring.data) { 00112 flags.bits.username = 1; 00113 } 00114 00115 if(options->password.cstring || options->password.lenstring.data) { 00116 flags.bits.password = 1; 00117 } 00118 00119 writeChar(&ptr, flags.all); 00120 writeInt(&ptr, options->keepAliveInterval); 00121 writeMQTTString(&ptr, options->clientID); 00122 if(options->willFlag) { 00123 writeMQTTString(&ptr, options->will.topicName); 00124 writeMQTTString(&ptr, options->will.message); 00125 } 00126 00127 if(flags.bits.username) { 00128 writeMQTTString(&ptr, options->username); 00129 } 00130 00131 if(flags.bits.password) { 00132 writeMQTTString(&ptr, options->password); 00133 } 00134 00135 *serialized_len = (uint32_t)(ptr - buf); 00136 00137 FUNC_EXIT_RC(SUCCESS); 00138 return SUCCESS; 00139 } 00140 00141 /** 00142 * Deserializes the supplied (wire) buffer into connack data - return code 00143 * @param sessionPresent the session present flag returned (only for MQTT 3.1.1) 00144 * @param connack_rc returned integer value of the connack return code 00145 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00146 * @param buflen the length in bytes of the data in the supplied buffer 00147 * @return MQTTReturnCode indicating function execution status 00148 */ 00149 MQTTReturnCode MQTTDeserialize_connack(unsigned char *sessionPresent, 00150 MQTTReturnCode *connack_rc, 00151 unsigned char *buf, size_t buflen) { 00152 MQTTHeader header = {0}; 00153 unsigned char *curdata = buf; 00154 unsigned char *enddata = NULL; 00155 MQTTReturnCode rc = FAILURE; 00156 uint32_t decodedLen = 0; 00157 uint32_t readBytesLen = 0; 00158 MQTTConnackFlags flags = {0}; 00159 unsigned char connack_rc_char; 00160 FUNC_ENTRY; 00161 if(NULL == sessionPresent || NULL == connack_rc || NULL == buf) { 00162 FUNC_EXIT_RC(MQTT_NULL_VALUE_ERROR); 00163 return MQTT_NULL_VALUE_ERROR; 00164 } 00165 00166 /* CONNACK header size is fixed at two bytes for fixed and 2 bytes for variable, 00167 * using that as minimum size 00168 * MQTT v3.1.1 Specification 3.2.1 */ 00169 if(4 > buflen) { 00170 FUNC_EXIT_RC(MQTTPACKET_BUFFER_TOO_SHORT); 00171 return MQTTPACKET_BUFFER_TOO_SHORT; 00172 } 00173 00174 header.byte = readChar(&curdata); 00175 if(CONNACK != header.bits.type) { 00176 FUNC_EXIT_RC(FAILURE); 00177 return FAILURE; 00178 } 00179 00180 /* read remaining length */ 00181 rc = MQTTPacket_decodeBuf(curdata, &decodedLen, &readBytesLen); 00182 if(SUCCESS != rc) { 00183 FUNC_EXIT_RC(rc); 00184 return rc; 00185 } 00186 00187 curdata += (readBytesLen); 00188 enddata = curdata + decodedLen; 00189 if(enddata - curdata < 2) { 00190 FUNC_EXIT_RC(FAILURE); 00191 return FAILURE; 00192 } 00193 00194 flags.all = readChar(&curdata); 00195 *sessionPresent = flags.bits.sessionpresent; 00196 00197 connack_rc_char = readChar(&curdata); 00198 switch(connack_rc_char) { 00199 case CONNACK_CONNECTION_ACCEPTED: 00200 *connack_rc = MQTT_CONNACK_CONNECTION_ACCEPTED; 00201 break; 00202 case CONANCK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR: 00203 *connack_rc = MQTT_CONANCK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR; 00204 break; 00205 case CONNACK_IDENTIFIER_REJECTED_ERROR: 00206 *connack_rc = MQTT_CONNACK_IDENTIFIER_REJECTED_ERROR; 00207 break; 00208 case CONNACK_SERVER_UNAVAILABLE_ERROR: 00209 *connack_rc = MQTT_CONNACK_SERVER_UNAVAILABLE_ERROR; 00210 break; 00211 case CONNACK_BAD_USERDATA_ERROR: 00212 *connack_rc = MQTT_CONNACK_BAD_USERDATA_ERROR; 00213 break; 00214 case CONNACK_NOT_AUTHORIZED_ERROR: 00215 *connack_rc = MQTT_CONNACK_NOT_AUTHORIZED_ERROR; 00216 break; 00217 default: 00218 *connack_rc = MQTT_CONNACK_UNKNOWN_ERROR; 00219 break; 00220 } 00221 00222 FUNC_EXIT_RC(SUCCESS); 00223 return SUCCESS; 00224 } 00225 00226 /** 00227 * Serializes a 0-length packet into the supplied buffer, ready for writing to a socket 00228 * @param buf the buffer into which the packet will be serialized 00229 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00230 * @param packettype the message type 00231 * @param serialized length 00232 * @return MQTTReturnCode indicating function execution status 00233 */ 00234 MQTTReturnCode MQTTSerialize_zero(unsigned char *buf, size_t buflen, 00235 unsigned char packetType, 00236 uint32_t *serialized_length) { 00237 MQTTHeader header = {0}; 00238 unsigned char *ptr = buf; 00239 MQTTReturnCode rc = MQTTPacket_InitHeader(&header, (MessageTypes)packetType, QOS0, 0, 0); 00240 00241 FUNC_ENTRY; 00242 if(NULL == buf || NULL == serialized_length) { 00243 FUNC_EXIT_RC(MQTT_NULL_VALUE_ERROR); 00244 return MQTT_NULL_VALUE_ERROR; 00245 } 00246 00247 /* Buffer should have at least 2 bytes for the header */ 00248 if(4 > buflen) { 00249 FUNC_EXIT_RC(MQTTPACKET_BUFFER_TOO_SHORT); 00250 return MQTTPACKET_BUFFER_TOO_SHORT; 00251 } 00252 00253 if(SUCCESS != rc) { 00254 FUNC_EXIT_RC(rc); 00255 return rc; 00256 } 00257 00258 /* write header */ 00259 writeChar(&ptr, header.byte); 00260 00261 /* write remaining length */ 00262 ptr += MQTTPacket_encode(ptr, 0); 00263 *serialized_length = (uint32_t)(ptr - buf); 00264 00265 FUNC_EXIT_RC(SUCCESS); 00266 return SUCCESS; 00267 } 00268 00269 00270 /** 00271 * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket 00272 * @param buf the buffer into which the packet will be serialized 00273 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00274 * @param serialized length 00275 * @return MQTTReturnCode indicating function execution status 00276 */ 00277 MQTTReturnCode MQTTSerialize_disconnect(unsigned char *buf, size_t buflen, 00278 uint32_t *serialized_length) { 00279 return MQTTSerialize_zero(buf, buflen, DISCONNECT, serialized_length); 00280 } 00281 00282 00283 /** 00284 * Serializes a pingreq packet into the supplied buffer, ready for writing to a socket 00285 * @param buf the buffer into which the packet will be serialized 00286 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00287 * @param serialized length 00288 * @return MQTTReturnCode indicating function execution status 00289 */ 00290 MQTTReturnCode MQTTSerialize_pingreq(unsigned char *buf, size_t buflen, 00291 uint32_t *serialized_length) { 00292 return MQTTSerialize_zero(buf, buflen, PINGREQ, serialized_length); 00293 } 00294 00295
Generated on Tue Jul 12 2022 14:16:20 by 1.7.2