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 Cayenne-MQTT-mbed 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 00019 #include <string.h> 00020 00021 /** 00022 * Determines the length of the MQTT connect packet that would be produced using the supplied connect options. 00023 * @param options the options to be used to build the connect packet 00024 * @return the length of buffer needed to contain the serialized version of the packet 00025 */ 00026 int MQTTSerialize_connectLength(MQTTPacket_connectData* options) 00027 { 00028 int len = 0; 00029 00030 00031 if (options->MQTTVersion == 3) 00032 len = 12; /* variable depending on MQTT or MQIsdp */ 00033 else if (options->MQTTVersion == 4) 00034 len = 10; 00035 00036 len += MQTTstrlen(options->clientID)+2; 00037 if (options->willFlag) 00038 len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2; 00039 if (options->username.cstring || options->username.lenstring.data) 00040 len += MQTTstrlen(options->username)+2; 00041 if (options->password.cstring || options->password.lenstring.data) 00042 len += MQTTstrlen(options->password)+2; 00043 00044 return len; 00045 } 00046 00047 00048 /** 00049 * Serializes the connect options into the buffer. 00050 * @param buf the buffer into which the packet will be serialized 00051 * @param len the length in bytes of the supplied buffer 00052 * @param options the options to be used to build the connect packet 00053 * @return serialized length, or error if 0 00054 */ 00055 int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options) 00056 { 00057 unsigned char *ptr = buf; 00058 MQTTHeader header = {0}; 00059 MQTTConnectFlags flags = {0}; 00060 int len = 0; 00061 int rc = -1; 00062 00063 if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen) 00064 { 00065 rc = MQTTPACKET_BUFFER_TOO_SHORT; 00066 goto exit; 00067 } 00068 00069 header.byte = 0; 00070 header.bits.type = CONNECT_MSG; 00071 writeChar(&ptr, header.byte); /* write header */ 00072 00073 ptr += MQTTPacket_encode(ptr, len); /* write remaining length */ 00074 00075 if (options->MQTTVersion == 4) 00076 { 00077 writeCString(&ptr, "MQTT"); 00078 writeChar(&ptr, (char) 4); 00079 } 00080 else 00081 { 00082 writeCString(&ptr, "MQIsdp"); 00083 writeChar(&ptr, (char) 3); 00084 } 00085 00086 flags.all = 0; 00087 flags.bits.cleansession = options->cleansession; 00088 flags.bits.will = (options->willFlag) ? 1 : 0; 00089 if (flags.bits.will) 00090 { 00091 flags.bits.willQoS = options->will.qos; 00092 flags.bits.willRetain = options->will.retained; 00093 } 00094 00095 if (options->username.cstring || options->username.lenstring.data) 00096 flags.bits.username = 1; 00097 if (options->password.cstring || options->password.lenstring.data) 00098 flags.bits.password = 1; 00099 00100 writeChar(&ptr, flags.all); 00101 writeInt(&ptr, options->keepAliveInterval); 00102 writeMQTTString(&ptr, options->clientID); 00103 if (options->willFlag) 00104 { 00105 writeMQTTString(&ptr, options->will.topicName); 00106 writeMQTTString(&ptr, options->will.message); 00107 } 00108 if (flags.bits.username) 00109 writeMQTTString(&ptr, options->username); 00110 if (flags.bits.password) 00111 writeMQTTString(&ptr, options->password); 00112 00113 rc = ptr - buf; 00114 00115 exit: 00116 return rc; 00117 } 00118 00119 00120 /** 00121 * Deserializes the supplied (wire) buffer into connack data - return code 00122 * @param sessionPresent the session present flag returned (only for MQTT 3.1.1) 00123 * @param connack_rc returned integer value of the connack return code 00124 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00125 * @param len the length in bytes of the data in the supplied buffer 00126 * @return error code. 1 is success, 0 is failure 00127 */ 00128 int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen) 00129 { 00130 MQTTHeader header = {0}; 00131 unsigned char* curdata = buf; 00132 unsigned char* enddata = NULL; 00133 int rc = 0; 00134 int mylen; 00135 MQTTConnackFlags flags = {0}; 00136 00137 header.byte = readChar(&curdata); 00138 if (header.bits.type != CONNACK_MSG) 00139 goto exit; 00140 00141 curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 00142 enddata = curdata + mylen; 00143 if (enddata - curdata < 2) 00144 goto exit; 00145 00146 flags.all = readChar(&curdata); 00147 *sessionPresent = flags.bits.sessionpresent; 00148 *connack_rc = readChar(&curdata); 00149 00150 rc = 1; 00151 exit: 00152 return rc; 00153 } 00154 00155 00156 /** 00157 * Serializes a 0-length packet into the supplied buffer, ready for writing to a socket 00158 * @param buf the buffer into which the packet will be serialized 00159 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00160 * @param packettype the message type 00161 * @return serialized length, or error if 0 00162 */ 00163 int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype) 00164 { 00165 MQTTHeader header = {0}; 00166 int rc = -1; 00167 unsigned char *ptr = buf; 00168 00169 if (buflen < 2) 00170 { 00171 rc = MQTTPACKET_BUFFER_TOO_SHORT; 00172 goto exit; 00173 } 00174 header.byte = 0; 00175 header.bits.type = packettype; 00176 writeChar(&ptr, header.byte); /* write header */ 00177 00178 ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */ 00179 rc = ptr - buf; 00180 exit: 00181 return rc; 00182 } 00183 00184 00185 /** 00186 * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket 00187 * @param buf the buffer into which the packet will be serialized 00188 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00189 * @return serialized length, or error if 0 00190 */ 00191 int MQTTSerialize_disconnect(unsigned char* buf, int buflen) 00192 { 00193 return MQTTSerialize_zero(buf, buflen, DISCONNECT_MSG); 00194 } 00195 00196 00197 /** 00198 * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket 00199 * @param buf the buffer into which the packet will be serialized 00200 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00201 * @return serialized length, or error if 0 00202 */ 00203 int MQTTSerialize_pingreq(unsigned char* buf, int buflen) 00204 { 00205 return MQTTSerialize_zero(buf, buflen, PINGREQ_MSG); 00206 }
Generated on Tue Jul 12 2022 21:31:38 by
1.7.2
