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 MQTTPacket by
MQTTConnectServer.c@13:5e60cd1a52e7, 2014-08-01 (annotated)
- Committer:
- Ian Craggs
- Date:
- Fri Aug 01 13:08:46 2014 +0100
- Revision:
- 13:5e60cd1a52e7
- Parent:
- 12:cd99ac9cb25a
- Parent:
- 9:3893bc7343f4
- Child:
- 14:c2052aee81de
Compiler warning removal
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
icraggs | 0:7734401cc1b4 | 1 | /******************************************************************************* |
icraggs | 0:7734401cc1b4 | 2 | * Copyright (c) 2014 IBM Corp. |
icraggs | 0:7734401cc1b4 | 3 | * |
icraggs | 0:7734401cc1b4 | 4 | * All rights reserved. This program and the accompanying materials |
icraggs | 0:7734401cc1b4 | 5 | * are made available under the terms of the Eclipse Public License v1.0 |
icraggs | 0:7734401cc1b4 | 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. |
icraggs | 0:7734401cc1b4 | 7 | * |
icraggs | 0:7734401cc1b4 | 8 | * The Eclipse Public License is available at |
icraggs | 0:7734401cc1b4 | 9 | * http://www.eclipse.org/legal/epl-v10.html |
icraggs | 0:7734401cc1b4 | 10 | * and the Eclipse Distribution License is available at |
icraggs | 0:7734401cc1b4 | 11 | * http://www.eclipse.org/org/documents/edl-v10.php. |
icraggs | 0:7734401cc1b4 | 12 | * |
icraggs | 0:7734401cc1b4 | 13 | * Contributors: |
icraggs | 0:7734401cc1b4 | 14 | * Ian Craggs - initial API and implementation and/or initial documentation |
icraggs | 0:7734401cc1b4 | 15 | *******************************************************************************/ |
icraggs | 0:7734401cc1b4 | 16 | |
icraggs | 0:7734401cc1b4 | 17 | #include "StackTrace.h" |
icraggs | 0:7734401cc1b4 | 18 | #include "MQTTPacket.h" |
icraggs | 0:7734401cc1b4 | 19 | #include <string.h> |
icraggs | 0:7734401cc1b4 | 20 | |
Ian Craggs |
12:cd99ac9cb25a | 21 | #define min(a, b) ((a < b) ? a : b) |
icraggs | 0:7734401cc1b4 | 22 | |
icraggs | 0:7734401cc1b4 | 23 | |
icraggs | 0:7734401cc1b4 | 24 | /** |
icraggs | 0:7734401cc1b4 | 25 | * Validates MQTT protocol name and version combinations |
icraggs | 0:7734401cc1b4 | 26 | * @param protocol the MQTT protocol name as an MQTTString |
icraggs | 0:7734401cc1b4 | 27 | * @param version the MQTT protocol version number, as in the connect packet |
icraggs | 0:7734401cc1b4 | 28 | * @return correct MQTT combination? 1 is true, 0 is false |
icraggs | 0:7734401cc1b4 | 29 | */ |
icraggs | 0:7734401cc1b4 | 30 | int MQTTPacket_checkVersion(MQTTString* protocol, int version) |
icraggs | 0:7734401cc1b4 | 31 | { |
icraggs | 0:7734401cc1b4 | 32 | int rc = 0; |
icraggs | 0:7734401cc1b4 | 33 | |
icraggs | 0:7734401cc1b4 | 34 | if (version == 3 && memcmp(protocol->lenstring.data, "MQIdsp", |
Ian Craggs |
12:cd99ac9cb25a | 35 | min(6, protocol->lenstring.len)) == 0) |
icraggs | 0:7734401cc1b4 | 36 | rc = 1; |
Ian Craggs |
12:cd99ac9cb25a | 37 | else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT", |
Ian Craggs |
12:cd99ac9cb25a | 38 | min(4, protocol->lenstring.len)) == 0) |
icraggs | 0:7734401cc1b4 | 39 | rc = 1; |
icraggs | 1:069ae45b7070 | 40 | return rc; |
icraggs | 0:7734401cc1b4 | 41 | } |
icraggs | 0:7734401cc1b4 | 42 | |
icraggs | 0:7734401cc1b4 | 43 | |
icraggs | 0:7734401cc1b4 | 44 | /** |
icraggs | 0:7734401cc1b4 | 45 | * Deserializes the supplied (wire) buffer into connect data structure |
icraggs | 0:7734401cc1b4 | 46 | * @param data the connect data structure to be filled out |
icraggs | 0:7734401cc1b4 | 47 | * @param buf the raw buffer data, of the correct length determined by the remaining length field |
icraggs | 0:7734401cc1b4 | 48 | * @param len the length in bytes of the data in the supplied buffer |
icraggs | 0:7734401cc1b4 | 49 | * @return error code. 1 is success, 0 is failure |
icraggs | 0:7734401cc1b4 | 50 | */ |
icraggs | 0:7734401cc1b4 | 51 | int MQTTDeserialize_connect(MQTTPacket_connectData* data, char* buf, int len) |
icraggs | 0:7734401cc1b4 | 52 | { |
icraggs | 0:7734401cc1b4 | 53 | MQTTHeader header; |
icraggs | 0:7734401cc1b4 | 54 | MQTTConnectFlags flags; |
icraggs | 0:7734401cc1b4 | 55 | char* curdata = buf; |
icraggs | 0:7734401cc1b4 | 56 | char* enddata = &buf[len]; |
icraggs | 0:7734401cc1b4 | 57 | int rc = 0; |
icraggs | 0:7734401cc1b4 | 58 | MQTTString Protocol; |
icraggs | 0:7734401cc1b4 | 59 | int version; |
icraggs | 0:7734401cc1b4 | 60 | int mylen = 0; |
icraggs | 0:7734401cc1b4 | 61 | |
icraggs | 0:7734401cc1b4 | 62 | FUNC_ENTRY; |
icraggs | 0:7734401cc1b4 | 63 | header.byte = readChar(&curdata); |
sam_grove | 9:3893bc7343f4 | 64 | header.byte = header.byte; // hush compiler warnings |
icraggs | 0:7734401cc1b4 | 65 | |
Ian Craggs |
12:cd99ac9cb25a | 66 | curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */ |
icraggs | 0:7734401cc1b4 | 67 | |
icraggs | 0:7734401cc1b4 | 68 | if (!readMQTTLenString(&Protocol, &curdata, enddata) || |
icraggs | 0:7734401cc1b4 | 69 | enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */ |
icraggs | 0:7734401cc1b4 | 70 | goto exit; |
icraggs | 0:7734401cc1b4 | 71 | |
icraggs | 0:7734401cc1b4 | 72 | version = (int)readChar(&curdata); /* Protocol version */ |
icraggs | 0:7734401cc1b4 | 73 | /* If we don't recognize the protocol version, we don't parse the connect packet on the |
icraggs | 0:7734401cc1b4 | 74 | * basis that we don't know what the format will be. |
icraggs | 0:7734401cc1b4 | 75 | */ |
icraggs | 0:7734401cc1b4 | 76 | if (MQTTPacket_checkVersion(&Protocol, version)) |
icraggs | 0:7734401cc1b4 | 77 | { |
icraggs | 0:7734401cc1b4 | 78 | flags.all = readChar(&curdata); |
icraggs | 0:7734401cc1b4 | 79 | data->cleansession = flags.bits.cleansession; |
icraggs | 0:7734401cc1b4 | 80 | data->keepAliveInterval = readInt(&curdata); |
icraggs | 0:7734401cc1b4 | 81 | if (!readMQTTLenString(&data->clientID, &curdata, enddata)) |
icraggs | 0:7734401cc1b4 | 82 | goto exit; |
icraggs | 0:7734401cc1b4 | 83 | if (flags.bits.will) |
icraggs | 0:7734401cc1b4 | 84 | { |
icraggs | 0:7734401cc1b4 | 85 | data->willFlag = 1; |
icraggs | 0:7734401cc1b4 | 86 | data->will.qos = flags.bits.willQoS; |
icraggs | 0:7734401cc1b4 | 87 | data->will.retained = flags.bits.willRetain; |
icraggs | 0:7734401cc1b4 | 88 | if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) || |
icraggs | 0:7734401cc1b4 | 89 | !readMQTTLenString(&data->will.message, &curdata, enddata)) |
icraggs | 0:7734401cc1b4 | 90 | goto exit; |
icraggs | 0:7734401cc1b4 | 91 | } |
icraggs | 0:7734401cc1b4 | 92 | if (flags.bits.username) |
icraggs | 0:7734401cc1b4 | 93 | { |
icraggs | 0:7734401cc1b4 | 94 | if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata)) |
icraggs | 0:7734401cc1b4 | 95 | goto exit; /* username flag set, but no username supplied - invalid */ |
icraggs | 0:7734401cc1b4 | 96 | if (flags.bits.password && |
icraggs | 0:7734401cc1b4 | 97 | (enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata))) |
icraggs | 0:7734401cc1b4 | 98 | goto exit; /* password flag set, but no password supplied - invalid */ |
icraggs | 0:7734401cc1b4 | 99 | } |
icraggs | 0:7734401cc1b4 | 100 | else if (flags.bits.password) |
icraggs | 0:7734401cc1b4 | 101 | goto exit; /* password flag set without username - invalid */ |
icraggs | 0:7734401cc1b4 | 102 | rc = 1; |
icraggs | 0:7734401cc1b4 | 103 | } |
icraggs | 0:7734401cc1b4 | 104 | exit: |
icraggs | 0:7734401cc1b4 | 105 | FUNC_EXIT_RC(rc); |
icraggs | 0:7734401cc1b4 | 106 | return rc; |
icraggs | 0:7734401cc1b4 | 107 | } |
icraggs | 0:7734401cc1b4 | 108 | |
icraggs | 0:7734401cc1b4 | 109 | |
icraggs | 0:7734401cc1b4 | 110 | /** |
icraggs | 0:7734401cc1b4 | 111 | * Serializes the connack packet into the supplied buffer. |
icraggs | 0:7734401cc1b4 | 112 | * @param buf the buffer into which the packet will be serialized |
icraggs | 0:7734401cc1b4 | 113 | * @param buflen the length in bytes of the supplied buffer |
icraggs | 0:7734401cc1b4 | 114 | * @param connack_rc the integer connack return code to be used |
icraggs | 0:7734401cc1b4 | 115 | * @return serialized length, or error if 0 |
icraggs | 0:7734401cc1b4 | 116 | */ |
icraggs | 0:7734401cc1b4 | 117 | int MQTTSerialize_connack(char* buf, int buflen, int connack_rc) |
icraggs | 0:7734401cc1b4 | 118 | { |
icraggs | 0:7734401cc1b4 | 119 | MQTTHeader header; |
icraggs | 0:7734401cc1b4 | 120 | int rc = 0; |
icraggs | 0:7734401cc1b4 | 121 | char *ptr = buf; |
icraggs | 0:7734401cc1b4 | 122 | |
icraggs | 0:7734401cc1b4 | 123 | FUNC_ENTRY; |
icraggs | 0:7734401cc1b4 | 124 | if (buflen < 2) |
icraggs | 0:7734401cc1b4 | 125 | { |
icraggs | 0:7734401cc1b4 | 126 | rc = MQTTPACKET_BUFFER_TOO_SHORT; |
icraggs | 0:7734401cc1b4 | 127 | goto exit; |
icraggs | 0:7734401cc1b4 | 128 | } |
icraggs | 0:7734401cc1b4 | 129 | header.byte = 0; |
icraggs | 0:7734401cc1b4 | 130 | header.bits.type = CONNACK; |
icraggs | 0:7734401cc1b4 | 131 | writeChar(&ptr, header.byte); /* write header */ |
icraggs | 0:7734401cc1b4 | 132 | |
icraggs | 0:7734401cc1b4 | 133 | ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ |
icraggs | 0:7734401cc1b4 | 134 | |
icraggs | 0:7734401cc1b4 | 135 | writeChar(&ptr, 0); /* compression byte - not used */ |
icraggs | 0:7734401cc1b4 | 136 | writeChar(&ptr, connack_rc); |
icraggs | 0:7734401cc1b4 | 137 | |
icraggs | 0:7734401cc1b4 | 138 | rc = ptr - buf; |
icraggs | 0:7734401cc1b4 | 139 | exit: |
icraggs | 0:7734401cc1b4 | 140 | FUNC_EXIT_RC(rc); |
icraggs | 0:7734401cc1b4 | 141 | return rc; |
icraggs | 0:7734401cc1b4 | 142 | } |
icraggs | 0:7734401cc1b4 | 143 |