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.
MQTTConnectServer.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 "StackTrace.h" 00018 #include "MQTTPacket.h" 00019 #include <string.h> 00020 00021 #define min(a, b) ((a < b) ? a : b) 00022 00023 00024 /** 00025 * Validates MQTT protocol name and version combinations 00026 * @param protocol the MQTT protocol name as an MQTTString 00027 * @param version the MQTT protocol version number, as in the connect packet 00028 * @return correct MQTT combination? 1 is true, 0 is false 00029 */ 00030 int MQTTPacket_checkVersion(MQTTString* protocol, int version) 00031 { 00032 int rc = 0; 00033 00034 if (version == 3 && memcmp(protocol->lenstring.data, "MQIsdp", 00035 min(6, protocol->lenstring.len)) == 0) 00036 rc = 1; 00037 else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT", 00038 min(4, protocol->lenstring.len)) == 0) 00039 rc = 1; 00040 return rc; 00041 } 00042 00043 00044 /** 00045 * Deserializes the supplied (wire) buffer into connect data structure 00046 * @param data the connect data structure to be filled out 00047 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00048 * @param len the length in bytes of the data in the supplied buffer 00049 * @return error code. 1 is success, 0 is failure 00050 */ 00051 int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len) 00052 { 00053 MQTTHeader header = {0}; 00054 MQTTConnectFlags flags = {0}; 00055 unsigned char* curdata = buf; 00056 unsigned char* enddata = &buf[len]; 00057 int rc = 0; 00058 MQTTString Protocol; 00059 int version; 00060 int mylen = 0; 00061 00062 FUNC_ENTRY; 00063 header.byte = readChar(&curdata); 00064 if (header.bits.type != CONNECT) 00065 goto exit; 00066 00067 curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */ 00068 00069 if (!readMQTTLenString(&Protocol, &curdata, enddata) || 00070 enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */ 00071 goto exit; 00072 00073 version = (int)readChar(&curdata); /* Protocol version */ 00074 /* If we don't recognize the protocol version, we don't parse the connect packet on the 00075 * basis that we don't know what the format will be. 00076 */ 00077 if (MQTTPacket_checkVersion(&Protocol, version)) 00078 { 00079 flags.all = readChar(&curdata); 00080 data->cleansession = flags.bits.cleansession; 00081 data->keepAliveInterval = readInt(&curdata); 00082 if (!readMQTTLenString(&data->clientID, &curdata, enddata)) 00083 goto exit; 00084 data->willFlag = flags.bits.will; 00085 if (flags.bits.will) 00086 { 00087 data->will.qos = flags.bits.willQoS; 00088 data->will.retained = flags.bits.willRetain; 00089 if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) || 00090 !readMQTTLenString(&data->will.message, &curdata, enddata)) 00091 goto exit; 00092 } 00093 if (flags.bits.username) 00094 { 00095 if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata)) 00096 goto exit; /* username flag set, but no username supplied - invalid */ 00097 if (flags.bits.password && 00098 (enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata))) 00099 goto exit; /* password flag set, but no password supplied - invalid */ 00100 } 00101 else if (flags.bits.password) 00102 goto exit; /* password flag set without username - invalid */ 00103 rc = 1; 00104 } 00105 exit: 00106 FUNC_EXIT_RC(rc); 00107 return rc; 00108 } 00109 00110 00111 /** 00112 * Serializes the connack packet into the supplied buffer. 00113 * @param buf the buffer into which the packet will be serialized 00114 * @param buflen the length in bytes of the supplied buffer 00115 * @param connack_rc the integer connack return code to be used 00116 * @param sessionPresent the MQTT 3.1.1 sessionPresent flag 00117 * @return serialized length, or error if 0 00118 */ 00119 int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent) 00120 { 00121 MQTTHeader header = {0}; 00122 int rc = 0; 00123 unsigned char *ptr = buf; 00124 MQTTConnackFlags flags = {0}; 00125 00126 FUNC_ENTRY; 00127 if (buflen < 2) 00128 { 00129 rc = MQTTPACKET_BUFFER_TOO_SHORT; 00130 goto exit; 00131 } 00132 header.byte = 0; 00133 header.bits.type = CONNACK; 00134 writeChar(&ptr, header.byte); /* write header */ 00135 00136 ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ 00137 00138 flags.all = 0; 00139 flags.bits.sessionpresent = sessionPresent; 00140 writeChar(&ptr, flags.all); 00141 writeChar(&ptr, connack_rc); 00142 00143 rc = ptr - buf; 00144 exit: 00145 FUNC_EXIT_RC(rc); 00146 return rc; 00147 } 00148
Generated on Thu Jul 14 2022 12:58:42 by
