/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore/qloggingcategory.h>
#include <QtCore/qsocketnotifier.h>
#include <QtCore/qtimer.h>

#include "bluetoothmanagement_p.h"
#include "bluez_data_p.h"
#include "../qbluetoothsocketbase_p.h"

#include <unistd.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <linux/capability.h>

#include <cerrno>

QT_BEGIN_NAMESPACE

// Packet data structures for Mgmt API bluez.git/doc/mgmt-api.txt

enum class EventCode {
    DeviceFound =       0x0012,
};

struct MgmtHdr {
    quint16 cmdCode;
    quint16 controllerIndex;
    quint16 length;
} __attribute__((packed));

struct MgmtEventDeviceFound {
    bdaddr_t bdaddr;
    quint8 type;
    quint8 rssi;
    quint32 flags;
    quint16 eirLength;
    quint8 eirData[0];
}  __attribute__((packed));


/*
 * This class encapsulates access to the Bluetooth Management API as introduced by
 * Linux kernel 3.4. Some Bluetooth information is not exposed via the usual DBus
 * API (e.g. the random/public address type info). In those cases we have to fall back
 * to this mgmt API.
 *
 * Note that opening such a Bluetooth mgmt socket requires CAP_NET_ADMIN (root) capability.
 *
 * Documentation can be found in bluez-git/doc/mgmt-api.txt
 */

Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)

// These structs and defines come straight from linux/capability.h.
// To avoid missing definitions we re-define them if not existing.
// In addition, we don't want to pull in a libcap2 dependency
struct capHdr {
    quint32 version;
    int pid;
};

struct capData {
    quint32 effective;
    quint32 permitted;
    quint32 inheritable;
};

#ifndef _LINUX_CAPABILITY_VERSION_3
#define _LINUX_CAPABILITY_VERSION_3 0x20080522
#endif

#ifndef _LINUX_CAPABILITY_U32S_3
#define _LINUX_CAPABILITY_U32S_3 2
#endif

#ifndef CAP_NET_ADMIN
#define CAP_NET_ADMIN 12
#endif

#ifndef CAP_TO_INDEX
#define CAP_TO_INDEX(x)     ((x) >> 5)        /* 1 << 5 == bits in __u32 */
#endif

#ifndef CAP_TO_MASK
#define CAP_TO_MASK(x)      (1 << ((x) & 31)) /* mask for indexed __u32 */
#endif

const int msecInADay = 1000*60*60*24;

inline uint qHash(const QBluetoothAddress& address)
{
    return qHash(address.toUInt64());
}

static int sysCallCapGet(capHdr *header, capData *data)
{
    return syscall(__NR_capget, header, data);
}

/*
 * Checks that the current process has the effective CAP_NET_ADMIN permission.
 */
static bool hasBtMgmtPermission()
{
    // We only care for cap version 3 introduced by kernel 2.6.26
    // because the new BlueZ management API only exists since kernel 3.4.

    struct capHdr header = {};
    struct capData data[_LINUX_CAPABILITY_U32S_3] = {{}};
    header.version = _LINUX_CAPABILITY_VERSION_3;
    header.pid = getpid();

    if (sysCallCapGet(&header, data) < 0) {
        qCWarning(QT_BT_BLUEZ, "BluetoothManangement: getCap failed with %s",
                               qPrintable(qt_error_string(errno)));
        return false;
    }

    return (data[CAP_TO_INDEX(CAP_NET_ADMIN)].effective & CAP_TO_MASK(CAP_NET_ADMIN));
}

BluetoothManagement::BluetoothManagement(QObject *parent) : QObject(parent)
{
    bool hasPermission = hasBtMgmtPermission();
    if (!hasPermission) {
        qCInfo(QT_BT_BLUEZ, "Missing CAP_NET_ADMIN permission. Cannot determine whether "
                             "a found address is of random or public type.");
        return;
    }

    sockaddr_hci hciAddr;

    fd = ::socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, BTPROTO_HCI);
    if (fd < 0) {
        qCWarning(QT_BT_BLUEZ, "Cannot open Bluetooth Management socket: %s",
                               qPrintable(qt_error_string(errno)));
        return;
    }

    memset(&hciAddr, 0, sizeof(hciAddr));
    hciAddr.hci_dev = HCI_DEV_NONE;
    hciAddr.hci_channel = HCI_CHANNEL_CONTROL;
    hciAddr.hci_family = AF_BLUETOOTH;

    if (::bind(fd, (struct sockaddr *)(&hciAddr), sizeof(hciAddr)) < 0) {
        qCWarning(QT_BT_BLUEZ, "Cannot bind Bluetooth Management socket: %s",
                               qPrintable(qt_error_string(errno)));
        ::close(fd);
        fd = -1;
        return;
    }

    notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
    connect(notifier, &QSocketNotifier::activated, this, &BluetoothManagement::_q_readNotifier);

    // ensure cache is regularly cleaned (once every 24h)
    QTimer* timer = new QTimer(this);
    timer->setInterval(msecInADay);
    timer->setTimerType(Qt::VeryCoarseTimer);
    connect(timer, &QTimer::timeout, this, &BluetoothManagement::cleanupOldAddressFlags);
    timer->start();
}

Q_GLOBAL_STATIC(BluetoothManagement, bluetoothKernelManager)

BluetoothManagement *BluetoothManagement::instance()
{
    return bluetoothKernelManager();
}

void BluetoothManagement::_q_readNotifier()
{
    char *dst = buffer.reserve(QPRIVATELINEARBUFFER_BUFFERSIZE);
    int readCount = ::read(fd, dst, QPRIVATELINEARBUFFER_BUFFERSIZE);
    buffer.chop(QPRIVATELINEARBUFFER_BUFFERSIZE - (readCount < 0 ? 0 : readCount));
    if (readCount < 0) {
        qCWarning(QT_BT_BLUEZ, "Management Control read error %s", qPrintable(qt_error_string(errno)));
        return;
    }

    // do we have at least one complete mgmt header?
    if ((uint)buffer.size() < sizeof(MgmtHdr))
        return;

    QByteArray data = buffer.readAll();

    while (true) {
        if ((uint)data.size() < sizeof(MgmtHdr))
            break;

        const MgmtHdr *hdr = reinterpret_cast<const MgmtHdr*>(data.constData());
        const int nextPackageSize = qFromLittleEndian(hdr->length) + sizeof(MgmtHdr);
        const int remainingPackageSize = data.length() - nextPackageSize;

        if (data.length() < nextPackageSize)
            break; // not a complete event header -> wait for next notifier

        switch (static_cast<EventCode>(qFromLittleEndian(hdr->cmdCode))) {
        case EventCode::DeviceFound:
        {
            const MgmtEventDeviceFound *event = reinterpret_cast<const MgmtEventDeviceFound*>
                                                   (data.constData() + sizeof(MgmtHdr));

            if (event->type == BDADDR_LE_RANDOM) {
                const bdaddr_t address = event->bdaddr;
                quint64 bdaddr;

                convertAddress(address.b, &bdaddr);
                const QBluetoothAddress qtAddress(bdaddr);
                qCDebug(QT_BT_BLUEZ) << "BluetoothManagement: found random device"
                                     << qtAddress;
                processRandomAddressFlagInformation(qtAddress);
            }

            break;
        }
        default:
            qCDebug(QT_BT_BLUEZ) << "BluetoothManagement: Ignored event:"
                                 << hex << qFromLittleEndian(hdr->cmdCode);
            break;
        }

        if (data.length() > nextPackageSize)
            data = data.right(remainingPackageSize);
        else
            data.clear();

        if (data.isEmpty())
            break;
    }

    if (!data.isEmpty())
        buffer.ungetBlock(data.constData(), data.size());
}

void BluetoothManagement::processRandomAddressFlagInformation(const QBluetoothAddress &address)
{
    // insert or update
    QMutexLocker locker(&accessLock);
    privateFlagAddresses[address] = QDateTime::currentDateTimeUtc();
}

/*
 * Ensure that private address cache is not older than 24h.
 */
void BluetoothManagement::cleanupOldAddressFlags()
{
    const auto cutOffTime = QDateTime::currentDateTimeUtc().addDays(-1);

    QMutexLocker locker(&accessLock);

    auto i = privateFlagAddresses.begin();
    while (i != privateFlagAddresses.end()) {
        if (i.value() < cutOffTime)
            i = privateFlagAddresses.erase(i);
        else
            i++;
    }
}

bool BluetoothManagement::isAddressRandom(const QBluetoothAddress &address) const
{
    if (fd == -1 || address.isNull())
        return false;

    QMutexLocker locker(&accessLock);
    return privateFlagAddresses.contains(address);
}

bool BluetoothManagement::isMonitoringEnabled() const
{
    return (fd == -1) ? false : true;
}


QT_END_NAMESPACE
