/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Javier S. Pedro <maemo@javispedro.com>
** 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 "hcimanager_p.h"

#include "qbluetoothsocketbase_p.h"
#include "qlowenergyconnectionparameters.h"

#include <QtCore/qloggingcategory.h>

#include <cstring>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <unistd.h>

QT_BEGIN_NAMESPACE

Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)

HciManager::HciManager(const QBluetoothAddress& deviceAdapter, QObject *parent) :
    QObject(parent), hciSocket(-1), hciDev(-1)
{
    hciSocket = ::socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI);
    if (hciSocket < 0) {
        qCWarning(QT_BT_BLUEZ) << "Cannot open HCI socket";
        return; //TODO error report
    }

    hciDev = hciForAddress(deviceAdapter);
    if (hciDev < 0) {
        qCWarning(QT_BT_BLUEZ) << "Cannot find hci dev for" << deviceAdapter.toString();
        close(hciSocket);
        hciSocket = -1;
        return;
    }

    struct sockaddr_hci addr;

    memset(&addr, 0, sizeof(struct sockaddr_hci));
    addr.hci_dev = hciDev;
    addr.hci_family = AF_BLUETOOTH;

    if (::bind(hciSocket, (struct sockaddr *) (&addr), sizeof(addr)) < 0) {
        qCWarning(QT_BT_BLUEZ) << "HCI bind failed:" << strerror(errno);
        close(hciSocket);
        hciSocket = hciDev = -1;
        return;
    }

    notifier = new QSocketNotifier(hciSocket, QSocketNotifier::Read, this);
    connect(notifier, SIGNAL(activated(QSocketDescriptor)), this, SLOT(_q_readNotify()));

}

HciManager::~HciManager()
{
    if (hciSocket >= 0)
        ::close(hciSocket);

}

bool HciManager::isValid() const
{
    if (hciSocket && hciDev >= 0)
        return true;
    return false;
}

int HciManager::hciForAddress(const QBluetoothAddress &deviceAdapter)
{
    if (hciSocket < 0)
        return -1;

    bdaddr_t adapter;
    convertAddress(deviceAdapter.toUInt64(), adapter.b);

    struct hci_dev_req *devRequest = nullptr;
    struct hci_dev_list_req *devRequestList = nullptr;
    struct hci_dev_info devInfo;
    const int devListSize = sizeof(struct hci_dev_list_req)
                        + HCI_MAX_DEV * sizeof(struct hci_dev_req);

    devRequestList = (hci_dev_list_req *) malloc(devListSize);
    if (!devRequestList)
        return -1;

    QScopedPointer<hci_dev_list_req, QScopedPointerPodDeleter> p(devRequestList);

    memset(p.data(), 0, devListSize);
    p->dev_num = HCI_MAX_DEV;
    devRequest = p->dev_req;

    if (ioctl(hciSocket, HCIGETDEVLIST, devRequestList) < 0)
        return -1;

    for (int i = 0; i < devRequestList->dev_num; i++) {
        devInfo.dev_id = (devRequest+i)->dev_id;
        if (ioctl(hciSocket, HCIGETDEVINFO, &devInfo) < 0) {
            continue;
        }

        int result = memcmp(&adapter, &devInfo.bdaddr, sizeof(bdaddr_t));
        if (result == 0 || deviceAdapter.isNull()) // addresses match
            return devInfo.dev_id;
    }

    return -1;
}

/*
 * Returns true if \a event was successfully enabled
 */
bool HciManager::monitorEvent(HciManager::HciEvent event)
{
    if (!isValid())
        return false;

    // this event is already enabled
    // TODO runningEvents does not seem to be used
    if (runningEvents.contains(event))
        return true;

    hci_filter filter;
    socklen_t length = sizeof(hci_filter);
    if (getsockopt(hciSocket, SOL_HCI, HCI_FILTER, &filter, &length) < 0) {
        qCWarning(QT_BT_BLUEZ) << "Cannot retrieve HCI filter settings";
        return false;
    }

    hci_filter_set_ptype(HCI_EVENT_PKT, &filter);
    hci_filter_set_event(event, &filter);
    //hci_filter_all_events(&filter);

    if (setsockopt(hciSocket, SOL_HCI, HCI_FILTER, &filter, sizeof(hci_filter)) < 0) {
        qCWarning(QT_BT_BLUEZ) << "Could not set HCI socket options:" << strerror(errno);
        return false;
    }

    return true;
}

bool HciManager::monitorAclPackets()
{
    if (!isValid())
        return false;

    hci_filter filter;
    socklen_t length = sizeof(hci_filter);
    if (getsockopt(hciSocket, SOL_HCI, HCI_FILTER, &filter, &length) < 0) {
        qCWarning(QT_BT_BLUEZ) << "Cannot retrieve HCI filter settings";
        return false;
    }

    hci_filter_set_ptype(HCI_ACL_PKT, &filter);
    hci_filter_all_events(&filter);

    if (setsockopt(hciSocket, SOL_HCI, HCI_FILTER, &filter, sizeof(hci_filter)) < 0) {
        qCWarning(QT_BT_BLUEZ) << "Could not set HCI socket options:" << strerror(errno);
        return false;
    }

    return true;
}

bool HciManager::sendCommand(OpCodeGroupField ogf, OpCodeCommandField ocf, const QByteArray &parameters)
{
    qCDebug(QT_BT_BLUEZ) << "sending command; ogf:" << ogf << "ocf:" << ocf;
    quint8 packetType = HCI_COMMAND_PKT;
    hci_command_hdr command = {
        opCodePack(ogf, ocf),
        static_cast<uint8_t>(parameters.count())
    };
    static_assert(sizeof command == 3, "unexpected struct size");
    struct iovec iv[3];
    iv[0].iov_base = &packetType;
    iv[0].iov_len  = 1;
    iv[1].iov_base = &command;
    iv[1].iov_len  = sizeof command;
    int ivn = 2;
    if (!parameters.isEmpty()) {
        iv[2].iov_base = const_cast<char *>(parameters.constData()); // const_cast is safe, since iov_base will not get modified.
        iv[2].iov_len  = parameters.count();
        ++ivn;
    }
    while (writev(hciSocket, iv, ivn) < 0) {
        if (errno == EAGAIN || errno == EINTR)
            continue;
        qCDebug(QT_BT_BLUEZ()) << "hci command failure:" << strerror(errno);
        return false;
    }
    qCDebug(QT_BT_BLUEZ) << "command sent successfully";
    return true;
}

/*
 * Unsubscribe from all events
 */
void HciManager::stopEvents()
{
    if (!isValid())
        return;

    hci_filter filter;
    hci_filter_clear(&filter);

    if (setsockopt(hciSocket, SOL_HCI, HCI_FILTER, &filter, sizeof(hci_filter)) < 0) {
        qCWarning(QT_BT_BLUEZ) << "Could not clear HCI socket options:" << strerror(errno);
        return;
    }

    runningEvents.clear();
}

QBluetoothAddress HciManager::addressForConnectionHandle(quint16 handle) const
{
    if (!isValid())
        return QBluetoothAddress();

    hci_conn_info *info;
    hci_conn_list_req *infoList;

    const int maxNoOfConnections = 20;
    infoList = (hci_conn_list_req *)
            malloc(sizeof(hci_conn_list_req) + maxNoOfConnections * sizeof(hci_conn_info));

    if (!infoList)
        return QBluetoothAddress();

    QScopedPointer<hci_conn_list_req, QScopedPointerPodDeleter> p(infoList);
    p->conn_num = maxNoOfConnections;
    p->dev_id = hciDev;
    info = p->conn_info;

    if (ioctl(hciSocket, HCIGETCONNLIST, (void *) infoList) < 0) {
        qCWarning(QT_BT_BLUEZ) << "Cannot retrieve connection list";
        return QBluetoothAddress();
    }

    for (int i = 0; i < infoList->conn_num; i++) {
        if (info[i].handle == handle)
            return QBluetoothAddress(convertAddress(info[i].bdaddr.b));
    }

    return QBluetoothAddress();
}

QVector<quint16> HciManager::activeLowEnergyConnections() const
{
    if (!isValid())
        return QVector<quint16>();

    hci_conn_info *info;
    hci_conn_list_req *infoList;

    const int maxNoOfConnections = 20;
    infoList = (hci_conn_list_req *)
            malloc(sizeof(hci_conn_list_req) + maxNoOfConnections * sizeof(hci_conn_info));

    if (!infoList)
        return QVector<quint16>();

    QScopedPointer<hci_conn_list_req, QScopedPointerPodDeleter> p(infoList);
    p->conn_num = maxNoOfConnections;
    p->dev_id = hciDev;
    info = p->conn_info;

    if (ioctl(hciSocket, HCIGETCONNLIST, (void *) infoList) < 0) {
        qCWarning(QT_BT_BLUEZ) << "Cannot retrieve connection list";
        return QVector<quint16>();
    }

    QVector<quint16> activeLowEnergyHandles;
    for (int i = 0; i < infoList->conn_num; i++) {
        switch (info[i].type) {
        case SCO_LINK:
        case ACL_LINK:
        case ESCO_LINK:
            continue;
        case LE_LINK:
            activeLowEnergyHandles.append(info[i].handle);
            break;
        default:
            qCWarning(QT_BT_BLUEZ) << "Unknown active connection type:" << hex << info[i].type;
            break;
        }
    }

    return activeLowEnergyHandles;
}

quint16 forceIntervalIntoRange(double connectionInterval)
{
    return qMin<double>(qMax<double>(7.5, connectionInterval), 4000) / 1.25;
}

struct ConnectionUpdateData {
    quint16 minInterval;
    quint16 maxInterval;
    quint16 slaveLatency;
    quint16 timeout;
};
ConnectionUpdateData connectionUpdateData(const QLowEnergyConnectionParameters &params)
{
    ConnectionUpdateData data;
    const quint16 minInterval = forceIntervalIntoRange(params.minimumInterval());
    const quint16 maxInterval = forceIntervalIntoRange(params.maximumInterval());
    data.minInterval = qToLittleEndian(minInterval);
    data.maxInterval = qToLittleEndian(maxInterval);
    const quint16 latency = qMax<quint16>(0, qMin<quint16>(params.latency(), 499));
    data.slaveLatency = qToLittleEndian(latency);
    const quint16 timeout
            = qMax<quint16>(100, qMin<quint16>(32000, params.supervisionTimeout())) / 10;
    data.timeout = qToLittleEndian(timeout);
    return data;
}

bool HciManager::sendConnectionUpdateCommand(quint16 handle,
                                             const QLowEnergyConnectionParameters &params)
{
    struct CommandParams {
        quint16 handle;
        ConnectionUpdateData data;
        quint16 minCeLength;
        quint16 maxCeLength;
    } commandParams;
    commandParams.handle = qToLittleEndian(handle);
    commandParams.data = connectionUpdateData(params);
    commandParams.minCeLength = 0;
    commandParams.maxCeLength = qToLittleEndian(quint16(0xffff));
    const QByteArray data = QByteArray::fromRawData(reinterpret_cast<char *>(&commandParams),
                                                    sizeof commandParams);
    return sendCommand(OgfLinkControl, OcfLeConnectionUpdate, data);
}

bool HciManager::sendConnectionParameterUpdateRequest(quint16 handle,
                                                      const QLowEnergyConnectionParameters &params)
{
    ConnectionUpdateData connUpdateData = connectionUpdateData(params);

    // Vol 3, part A, 4
    struct SignalingPacket {
        quint8 code;
        quint8 identifier;
        quint16 length;
    } signalingPacket;
    signalingPacket.code = 0x12;
    signalingPacket.identifier = ++sigPacketIdentifier;
    const quint16 sigPacketLen = sizeof connUpdateData;
    signalingPacket.length = qToLittleEndian(sigPacketLen);

    L2CapHeader l2CapHeader;
    const quint16 l2CapHeaderLen = sizeof signalingPacket + sigPacketLen;
    l2CapHeader.length = qToLittleEndian(l2CapHeaderLen);
    l2CapHeader.channelId = qToLittleEndian(quint16(SIGNALING_CHANNEL_ID));

    // Vol 2, part E, 5.4.2
    AclData aclData;
    aclData.handle = qToLittleEndian(handle); // Works because the next two values are zero.
    aclData.pbFlag = 0;
    aclData.bcFlag = 0;
    aclData.dataLen = qToLittleEndian(quint16(sizeof l2CapHeader + l2CapHeaderLen));

    struct iovec iv[5];
    quint8 packetType = HCI_ACL_PKT;
    iv[0].iov_base = &packetType;
    iv[0].iov_len  = 1;
    iv[1].iov_base = &aclData;
    iv[1].iov_len  = sizeof aclData;
    iv[2].iov_base = &l2CapHeader;
    iv[2].iov_len = sizeof l2CapHeader;
    iv[3].iov_base = &signalingPacket;
    iv[3].iov_len = sizeof signalingPacket;
    iv[4].iov_base = &connUpdateData;
    iv[4].iov_len = sizeof connUpdateData;
    while (writev(hciSocket, iv, sizeof iv / sizeof *iv) < 0) {
        if (errno == EAGAIN || errno == EINTR)
            continue;
        qCDebug(QT_BT_BLUEZ()) << "failure writing HCI ACL packet:" << strerror(errno);
        return false;
    }
    qCDebug(QT_BT_BLUEZ) << "Connection Update Request packet sent successfully";
    return true;
}

/*!
 * Process all incoming HCI events. Function cannot process anything else but events.
 */
void HciManager::_q_readNotify()
{
    unsigned char buffer[qMax<int>(HCI_MAX_EVENT_SIZE, sizeof(AclData))];
    int size;

    size = ::read(hciSocket, buffer, sizeof(buffer));
    if (size < 0) {
        if (errno != EAGAIN && errno != EINTR)
            qCWarning(QT_BT_BLUEZ) << "Failed reading HCI events:" << qt_error_string(errno);

        return;
    }

    switch (buffer[0]) {
    case HCI_EVENT_PKT:
        handleHciEventPacket(buffer + 1, size - 1);
        break;
    case HCI_ACL_PKT:
        handleHciAclPacket(buffer + 1, size - 1);
        break;
    default:
        qCWarning(QT_BT_BLUEZ) << "Ignoring unexpected HCI packet type" << buffer[0];
    }
}

void HciManager::handleHciEventPacket(const quint8 *data, int size)
{
    if (size < HCI_EVENT_HDR_SIZE) {
        qCWarning(QT_BT_BLUEZ) << "Unexpected HCI event packet size:" << size;
        return;
    }

    hci_event_hdr *header = (hci_event_hdr *) data;

    size -= HCI_EVENT_HDR_SIZE;
    data += HCI_EVENT_HDR_SIZE;

    if (header->plen != size) {
        qCWarning(QT_BT_BLUEZ) << "Invalid HCI event packet size";
        return;
    }

    qCDebug(QT_BT_BLUEZ) << "HCI event triggered, type:" << hex << header->evt;

    switch (header->evt) {
    case EVT_ENCRYPT_CHANGE:
    {
        const evt_encrypt_change *event = (evt_encrypt_change *) data;
        qCDebug(QT_BT_BLUEZ) << "HCI Encrypt change, status:"
                             << (event->status == 0 ? "Success" : "Failed")
                             << "handle:" << hex << event->handle
                             << "encrypt:" << event->encrypt;

        QBluetoothAddress remoteDevice = addressForConnectionHandle(event->handle);
        if (!remoteDevice.isNull())
            emit encryptionChangedEvent(remoteDevice, event->status == 0);
    }
        break;
    case EVT_CMD_COMPLETE: {
        auto * const event = reinterpret_cast<const evt_cmd_complete *>(data);
        static_assert(sizeof *event == 3, "unexpected struct size");

        // There is always a status byte right after the generic structure.
        Q_ASSERT(size > static_cast<int>(sizeof *event));
        const quint8 status = data[sizeof *event];
        const auto additionalData = QByteArray(reinterpret_cast<const char *>(data)
                                               + sizeof *event + 1, size - sizeof *event - 1);
        emit commandCompleted(event->opcode, status, additionalData);
    }
        break;
    case LeMetaEvent:
        handleLeMetaEvent(data);
        break;
    default:
        break;
    }

}

void HciManager::handleHciAclPacket(const quint8 *data, int size)
{
    if (size < int(sizeof(AclData))) {
        qCWarning(QT_BT_BLUEZ) << "Unexpected HCI ACL packet size";
        return;
    }

    quint16 rawAclData[sizeof(AclData) / sizeof(quint16)];
    rawAclData[0] = bt_get_le16(data);
    rawAclData[1] = bt_get_le16(data + sizeof(quint16));
    const AclData *aclData = reinterpret_cast<AclData *>(rawAclData);
    data += sizeof *aclData;
    size -= sizeof *aclData;

    // Consider only directed, complete messages.
    if ((aclData->pbFlag != 0 && aclData->pbFlag != 2) || aclData->bcFlag != 0)
        return;

    if (size < aclData->dataLen) {
        qCWarning(QT_BT_BLUEZ) << "HCI ACL packet data size" << size
                               << "is smaller than specified size" << aclData->dataLen;
        return;
    }

//    qCDebug(QT_BT_BLUEZ) << "handle:" << aclData->handle << "PB:" << aclData->pbFlag
//                         << "BC:" << aclData->bcFlag << "data len:" << aclData->dataLen;

    if (size < int(sizeof(L2CapHeader))) {
        qCWarning(QT_BT_BLUEZ) << "Unexpected HCI ACL packet size";
        return;
    }
    L2CapHeader l2CapHeader = *reinterpret_cast<const L2CapHeader*>(data);
    l2CapHeader.channelId = qFromLittleEndian(l2CapHeader.channelId);
    l2CapHeader.length = qFromLittleEndian(l2CapHeader.length);
    data += sizeof l2CapHeader;
    size -= sizeof l2CapHeader;
    if (size < l2CapHeader.length) {
        qCWarning(QT_BT_BLUEZ) << "L2Cap payload size" << size << "is smaller than specified size"
                               << l2CapHeader.length;
        return;
    }
//    qCDebug(QT_BT_BLUEZ) << "l2cap channel id:" << l2CapHeader.channelId
//                         << "payload length:" << l2CapHeader.length;
    if (l2CapHeader.channelId != SECURITY_CHANNEL_ID)
        return;
    if (*data != 0xa) // "Signing Information". Spec v4.2, Vol 3, Part H, 3.6.6
        return;
    if (size != 17) {
        qCWarning(QT_BT_BLUEZ) << "Unexpected key size" << size << "in Signing Information packet";
        return;
    }
    quint128 csrk;
    memcpy(&csrk, data + 1, sizeof csrk);
    const bool isRemoteKey = aclData->pbFlag == 2;
    emit signatureResolvingKeyReceived(aclData->handle, isRemoteKey, csrk);
}

void HciManager::handleLeMetaEvent(const quint8 *data)
{
    // Spec v4.2, Vol 2, part E, 7.7.65ff
    switch (*data) {
    case 0x1: {
        const quint16 handle = bt_get_le16(data + 2);
        emit connectionComplete(handle);
        break;
    }
    case 0x3: {
        // TODO: From little endian!
        struct ConnectionUpdateData {
            quint8 status;
            quint16 handle;
            quint16 interval;
            quint16 latency;
            quint16 timeout;
        } __attribute((packed));
        const auto * const updateData
                = reinterpret_cast<const ConnectionUpdateData *>(data + 1);
        if (updateData->status == 0) {
            QLowEnergyConnectionParameters params;
            const double interval = qFromLittleEndian(updateData->interval) * 1.25;
            params.setIntervalRange(interval, interval);
            params.setLatency(qFromLittleEndian(updateData->latency));
            params.setSupervisionTimeout(qFromLittleEndian(updateData->timeout) * 10);
            emit connectionUpdate(qFromLittleEndian(updateData->handle), params);
        }
        break;
    }
    default:
        break;
    }
}

QT_END_NAMESPACE
