/*
 * This file was generated by qdbusxml2cpp version 0.8
 * Command line was: qdbusxml2cpp -p gattservice1_p.h:gattservice1.cpp org.bluez.GattService1.xml
 *
 * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd.
 *
 * This is an auto-generated file.
 * Do not edit! All changes made to it will be lost.
 */

#ifndef GATTSERVICE1_P_H
#define GATTSERVICE1_P_H

#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>

/*
 * Proxy class for interface org.bluez.GattService1
 */
class OrgBluezGattService1Interface: public QDBusAbstractInterface
{
    Q_OBJECT
public:
    static inline const char *staticInterfaceName()
    { return "org.bluez.GattService1"; }

public:
    OrgBluezGattService1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);

    ~OrgBluezGattService1Interface();

    Q_PROPERTY(QDBusObjectPath Device READ device)
    inline QDBusObjectPath device() const
    { return qvariant_cast< QDBusObjectPath >(property("Device")); }

    Q_PROPERTY(QList<QDBusObjectPath> Includes READ includes)
    inline QList<QDBusObjectPath> includes() const
    { return qvariant_cast< QList<QDBusObjectPath> >(property("Includes")); }

    Q_PROPERTY(bool Primary READ primary)
    inline bool primary() const
    { return qvariant_cast< bool >(property("Primary")); }

    Q_PROPERTY(QString UUID READ uUID)
    inline QString uUID() const
    { return qvariant_cast< QString >(property("UUID")); }

public Q_SLOTS: // METHODS
Q_SIGNALS: // SIGNALS
};

namespace org {
  namespace bluez {
    typedef ::OrgBluezGattService1Interface GattService1;
  }
}
#endif
