Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os-example-mbed5-blinky by
MQTTConnectClient.c
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 * @return the length of buffer needed to contain the serialized version of the packet 00026 */ 00027 int MQTTSerialize_connectLength(MQTTPacket_connectData* options) 00028 { 00029 int len = 0; 00030 00031 FUNC_ENTRY; 00032 00033 if (options->MQTTVersion == 3) 00034 len = 12; /* variable depending on MQTT or MQIsdp */ 00035 else if (options->MQTTVersion == 4) 00036 len = 10; 00037 00038 len += MQTTstrlen(options->clientID)+2; 00039 if (options->willFlag) 00040 len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2; 00041 if (options->username.cstring || options->username.lenstring.data) 00042 len += MQTTstrlen(options->username)+2; 00043 if (options->password.cstring || options->password.lenstring.data) 00044 len += MQTTstrlen(options->password)+2; 00045 00046 FUNC_EXIT_RC(len); 00047 return len; 00048 } 00049 00050 00051 /** 00052 * Serializes the connect options into the buffer. 00053 * @param buf the buffer into which the packet will be serialized 00054 * @param len the length in bytes of the supplied buffer 00055 * @param options the options to be used to build the connect packet 00056 * @return serialized length, or error if 0 00057 */ 00058 int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options) 00059 { 00060 unsigned char *ptr = buf; 00061 MQTTHeader header = {0}; 00062 MQTTConnectFlags flags = {0}; 00063 int len = 0; 00064 int rc = -1; 00065 00066 FUNC_ENTRY; 00067 if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen) 00068 { 00069 rc = MQTTPACKET_BUFFER_TOO_SHORT; 00070 goto exit; 00071 } 00072 00073 header.byte = 0; 00074 header.bits.type = CONNECT; 00075 writeChar(&ptr, header.byte); /* write header */ 00076 00077 ptr += MQTTPacket_encode(ptr, len); /* write remaining length */ 00078 00079 if (options->MQTTVersion == 4) 00080 { 00081 writeCString(&ptr, "MQTT"); 00082 writeChar(&ptr, (char) 4); 00083 } 00084 else 00085 { 00086 writeCString(&ptr, "MQIsdp"); 00087 writeChar(&ptr, (char) 3); 00088 } 00089 00090 flags.all = 0; 00091 flags.bits.cleansession = options->cleansession; 00092 flags.bits.will = (options->willFlag) ? 1 : 0; 00093 if (flags.bits.will) 00094 { 00095 flags.bits.willQoS = options->will.qos; 00096 flags.bits.willRetain = options->will.retained; 00097 } 00098 00099 if (options->username.cstring || options->username.lenstring.data) 00100 flags.bits.username = 1; 00101 if (options->password.cstring || options->password.lenstring.data) 00102 flags.bits.password = 1; 00103 00104 writeChar(&ptr, flags.all); 00105 writeInt(&ptr, options->keepAliveInterval); 00106 writeMQTTString(&ptr, options->clientID); 00107 if (options->willFlag) 00108 { 00109 writeMQTTString(&ptr, options->will.topicName); 00110 writeMQTTString(&ptr, options->will.message); 00111 } 00112 if (flags.bits.username) 00113 writeMQTTString(&ptr, options->username); 00114 if (flags.bits.password) 00115 writeMQTTString(&ptr, options->password); 00116 00117 rc = ptr - buf; 00118 00119 exit: FUNC_EXIT_RC(rc); 00120 return rc; 00121 } 00122 00123 00124 /** 00125 * Deserializes the supplied (wire) buffer into connack data - return code 00126 * @param sessionPresent the session present flag returned (only for MQTT 3.1.1) 00127 * @param connack_rc returned integer value of the connack return code 00128 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00129 * @param len the length in bytes of the data in the supplied buffer 00130 * @return error code. 1 is success, 0 is failure 00131 */ 00132 int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen) 00133 { 00134 MQTTHeader header = {0}; 00135 unsigned char* curdata = buf; 00136 unsigned char* enddata = NULL; 00137 int rc = 0; 00138 int mylen; 00139 MQTTConnackFlags flags = {0}; 00140 00141 FUNC_ENTRY; 00142 header.byte = readChar(&curdata); 00143 if (header.bits.type != CONNACK) 00144 goto exit; 00145 00146 curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 00147 enddata = curdata + mylen; 00148 if (enddata - curdata < 2) 00149 goto exit; 00150 00151 flags.all = readChar(&curdata); 00152 *sessionPresent = flags.bits.sessionpresent; 00153 *connack_rc = readChar(&curdata); 00154 00155 rc = 1; 00156 exit: 00157 FUNC_EXIT_RC(rc); 00158 return rc; 00159 } 00160 00161 00162 00163 /** 00164 * Serializes a 0-length packet into the supplied buffer, ready for writing to a socket 00165 * @param buf the buffer into which the packet will be serialized 00166 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00167 * @param packettype the message type 00168 * @return serialized length, or error if 0 00169 */ 00170 int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype) 00171 { 00172 MQTTHeader header = {0}; 00173 int rc = -1; 00174 unsigned char *ptr = buf; 00175 00176 FUNC_ENTRY; 00177 if (buflen < 2) 00178 { 00179 rc = MQTTPACKET_BUFFER_TOO_SHORT; 00180 goto exit; 00181 } 00182 header.byte = 0; 00183 header.bits.type = packettype; 00184 writeChar(&ptr, header.byte); /* write header */ 00185 00186 ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */ 00187 rc = ptr - buf; 00188 exit: 00189 FUNC_EXIT_RC(rc); 00190 return rc; 00191 } 00192 00193 00194 /** 00195 * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket 00196 * @param buf the buffer into which the packet will be serialized 00197 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00198 * @return serialized length, or error if 0 00199 */ 00200 int MQTTSerialize_disconnect(unsigned char* buf, int buflen) 00201 { 00202 return MQTTSerialize_zero(buf, buflen, DISCONNECT); 00203 } 00204 00205 00206 /** 00207 * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket 00208 * @param buf the buffer into which the packet will be serialized 00209 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00210 * @return serialized length, or error if 0 00211 */ 00212 int MQTTSerialize_pingreq(unsigned char* buf, int buflen) 00213 { 00214 return MQTTSerialize_zero(buf, buflen, PINGREQ); 00215 }
Generated on Wed Jul 13 2022 21:16:17 by
