[OpenDocString] kdeconnect-kde (cpp)
bluetoothdevicelink.cpp
BluetoothDeviceLink::BluetoothDeviceLink(const QString &deviceId,
                                         LinkProvider *parent,
                                         ConnectionMultiplexer *connection,
                                         QSharedPointer socket)
    : DeviceLink(deviceId, parent)
    , mSocketReader(new DeviceLineReader(socket.data(), this))
    , mConnection(connection)
    , mChannel(socket)
    , mPairingHandler(new BluetoothPairingHandler(this))
{
    connect(mSocketReader, &DeviceLineReader::readyRead, this, &BluetoothDeviceLink::dataReceived);

    // We take ownership of the connection.
    // When the link provider destroys us,
    // the socket (and the reader) will be
    // destroyed as well
    mConnection->setParent(this);
    connect(socket.data(), &MultiplexChannel::aboutToClose, this, &QObject::deleteLater);
}
This constructs a device link object from an existing socket and a parent device link object. It takes ownership of the socket and sets the parent connection to this device link object. It also connects the socket to the pairing handler, and sets the parent connection to the parent object.
QString BluetoothDeviceLink::name()
{
    return QStringLiteral("BluetoothLink"); // Should be same in both android and kde version
}
Returns the name as a QString.
bool BluetoothDeviceLink::sendPacket(NetworkPacket &np)
{
    if (np.hasPayload()) {
        BluetoothUploadJob *uploadJob = new BluetoothUploadJob(np.payload(), mConnection, this);
        np.setPayloadTransferInfo(uploadJob->transferInfo());
        uploadJob->start();
    }
    // TODO: handle too-big packets
    int written = mSocketReader->write(np.serialize());
    return (written != -1);
}
This sends a network packet, if it has a payload, it will be uploaded to the device and sent to the device over the network. It returns true on the first successful write.
void BluetoothDeviceLink::userRequestsPair()
{
    mPairingHandler->requestPairing();
}
This requests that the device be paired.
void BluetoothDeviceLink::userRequestsUnpair()
{
    mPairingHandler->unpair();
}
This removes the pairing handler upon user requests.
bool BluetoothDeviceLink::linkShouldBeKeptAlive()
{
    return pairStatus() == Paired;
}
This implements checking if the link is already alive.
void BluetoothDeviceLink::dataReceived()
{
    if (mSocketReader->bytesAvailable() == 0)
        return;

    const QByteArray serializedPacket = mSocketReader->readLine();

    // qCDebug(KDECONNECT_CORE) << "BluetoothDeviceLink dataReceived" << packet;

    NetworkPacket packet((QString()));
    NetworkPacket::unserialize(serializedPacket, &packet);

    if (packet.type() == PACKET_TYPE_PAIR) {
        // TODO: Handle pair/unpair requests and forward them (to the pairing handler?)
        mPairingHandler->packetReceived(packet);
        return;
    }

    if (packet.hasPayloadTransferInfo()) {
        BluetoothDownloadJob *downloadJob = new BluetoothDownloadJob(mConnection, packet.payloadTransferInfo(), this);
        downloadJob->start();
        packet.setPayload(downloadJob->payload(), packet.payloadSize());
    }

    Q_EMIT receivedPacket(packet);

    if (mSocketReader->bytesAvailable() > 0) {
        QMetaObject::invokeMethod(this, &BluetoothDeviceLink::dataReceived, Qt::QueuedConnection);
    }
}
This reads a packet from the socket and converts it to a NetworkPacket. It first deserializes the packet, then it checks if the packet is a PAIR packet, if it is a PACKET_TYPE_PAIR, it will forward the requests to the pairing handler, otherwise it will emit the packet to the received packet method. Finally, it invokes the dataReceived method with a QQueuedConnection object that stores the packet in the packet.
QSslCertificate BluetoothDeviceLink::certificate() const
{
    return {}; // TODO Not sure what to do here. For LanDeviceLink we use the SSL connection's certificate, but we don't have that here
}
Returns an empty certificate object.