/****************************************************************************
**
** 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(int)), 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
