The Cayenne MQTT mbed Library provides functions to easily connect to the Cayenne IoT project builder.
Dependents: Cayenne-ESP8266Interface Cayenne-WIZnet_Library Cayenne-WIZnetInterface Cayenne-X-NUCLEO-IDW01M1 ... more
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 size_t MQTTSerialize_connectLength(MQTTPacket_connectData* options) 00027 { 00028 size_t 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, size_t buflen, MQTTPacket_connectData* options) 00056 { 00057 unsigned char *ptr = buf; 00058 MQTTHeader header = {0}; 00059 MQTTConnectFlags flags = {0}; 00060 size_t 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 = (int)(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, size_t 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, size_t 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 = (int)(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, size_t 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, size_t buflen) 00204 { 00205 return MQTTSerialize_zero(buf, buflen, PINGREQ_MSG); 00206 }
Generated on Wed Jul 13 2022 15:49:28 by 1.7.2