qmqtt_frame.h 4.36 KB
/* ****************************************************************************
 * Copyright 2019 Open Systems Development BV                                 *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *
 * DEALINGS IN THE SOFTWARE.                                                  *
 * ***************************************************************************/
#ifndef QMQTT_FRAME_H
#define QMQTT_FRAME_H

#include "qmqtt_global.h"

#include <QMetaType>
#include <QByteArray>
#include <QString>

QT_FORWARD_DECLARE_CLASS(QDataStream)

#define PROTOCOL_MAGIC_3_1_0 "MQIsdp"
#define PROTOCOL_MAGIC_3_1_1 "MQTT"

#define RANDOM_CLIENT_PREFIX "QMQTT-"

#define CONNECT 0x10
#define CONNACK 0x20
#define PUBLISH 0x30
#define PUBACK 0x40
#define PUBREC 0x50
#define PUBREL 0x60
#define PUBCOMP 0x70
#define SUBSCRIBE 0x80
#define SUBACK 0x90
#define UNSUBSCRIBE 0xA0
#define UNSUBACK 0xB0
#define PINGREQ 0xC0
#define PINGRESP 0xD0
#define DISCONNECT 0xE0

#define LSB(A) quint8(A & 0x00FF)
#define MSB(A) quint8((A & 0xFF00) >> 8)

/*
|--------------------------------------
| 7 6 5 4 |     3    |  2 1  | 0      |
|  Type   | DUP flag |  QoS  | RETAIN |
|--------------------------------------
*/
#define GETTYPE(HDR)		(HDR & 0xF0)
#define SETQOS(HDR, Q)		(HDR | ((Q) << 1))
#define GETQOS(HDR)			((HDR & 0x06) >> 1)
#define SETDUP(HDR, D)		(HDR | ((D) << 3))
#define GETDUP(HDR)			((HDR & 0x08) >> 3)
#define SETRETAIN(HDR, R)	(HDR | (R))
#define GETRETAIN(HDR)		(HDR & 0x01)

/*
|----------------------------------------------------------------------------------
|     7    |    6     |      5     |  4   3  |     2    |       1      |     0    |
| username | password | willretain | willqos | willflag | cleansession | reserved |
|----------------------------------------------------------------------------------
*/
#define FLAG_CLEANSESS(F, C)	(F | ((C) << 1))
#define FLAG_WILL(F, W)			(F | ((W) << 2))
#define FLAG_WILLQOS(F, Q)		(F | ((Q) << 3))
#define FLAG_WILLRETAIN(F, R) 	(F | ((R) << 5))
#define FLAG_PASSWD(F, P)		(F | ((P) << 6))
#define FLAG_USERNAME(F, U)		(F | ((U) << 7))

namespace QMQTT {

class Q_MQTT_EXPORT Frame
{
public:
    explicit Frame();
    explicit Frame(const quint8 header);
    explicit Frame(const quint8 header, const QByteArray &data);
    virtual ~Frame();

    Frame(const Frame& other);
    Frame& operator=(const Frame& other);

    bool operator==(const Frame& other) const;
    inline bool operator!=(const Frame& other) const
    { return !operator==(other); }

    quint8 header() const;
    QByteArray data() const;

    quint16 readInt();
    quint8 readChar();
    QByteArray readByteArray();
    QString readString();

    void writeInt(const quint16 i);
    void writeChar(const quint8 c);
    void writeByteArray(const QByteArray &data);
    void writeString(const QString &string);
    void writeRawData(const QByteArray &data);

    //TODO: FIXME LATER
    void write(QDataStream &stream) const;
    bool encodeLength(QByteArray &lenbuf, int length) const;

private:
    quint8 _header;
    QByteArray _data;
};

} // namespace QMQTT

Q_DECLARE_METATYPE(QMQTT::Frame)

#endif // QMQTT_FRAME_H