Vergil Cola
/
MQTTGateway2
Fork of my original MQTTGateway
Embed:
(wiki syntax)
Show/hide line numbers
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, "MQIdsp", 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 if (flags.bits.will) 00085 { 00086 data->willFlag = 1; 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 Tue Jul 12 2022 18:06:46 by 1.7.2