mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-02-16 22:28:14 +00:00
move files across computers
This commit is contained in:
53
linux/AirPodsTrayApp.h
Normal file
53
linux/AirPodsTrayApp.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QMenu>
|
||||
#include <QBluetoothDeviceDiscoveryAgent>
|
||||
#include <QBluetoothSocket>
|
||||
#include <QDBusInterface>
|
||||
#include "BluetoothHandler.h"
|
||||
|
||||
class AirPodsTrayApp : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AirPodsTrayApp();
|
||||
|
||||
public slots:
|
||||
void connectToDevice(const QString &address);
|
||||
void showAvailableDevices();
|
||||
void setNoiseControlMode(int mode);
|
||||
void setConversationalAwareness(bool enabled);
|
||||
void updateNoiseControlMenu(int mode);
|
||||
void updateBatteryTooltip(const QString &status);
|
||||
void updateTrayIcon(const QString &status);
|
||||
void handleEarDetection(const QString &status);
|
||||
|
||||
private slots:
|
||||
void onTrayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
void onDeviceDiscovered(const QBluetoothDeviceInfo &device);
|
||||
void onDiscoveryFinished();
|
||||
void onDeviceConnected(const QBluetoothAddress &address);
|
||||
void onDeviceDisconnected(const QBluetoothAddress &address);
|
||||
void onPhoneDataReceived();
|
||||
|
||||
signals:
|
||||
void noiseControlModeChanged(int mode);
|
||||
void earDetectionStatusChanged(const QString &status);
|
||||
void batteryStatusChanged(const QString &status);
|
||||
|
||||
private:
|
||||
void initializeMprisInterface();
|
||||
void connectToPhone();
|
||||
void relayPacketToPhone(const QByteArray &packet);
|
||||
void handlePhonePacket(const QByteArray &packet);
|
||||
|
||||
QSystemTrayIcon *trayIcon;
|
||||
QMenu *trayMenu;
|
||||
QBluetoothDeviceDiscoveryAgent *discoveryAgent;
|
||||
QBluetoothSocket *socket = nullptr;
|
||||
QBluetoothSocket *phoneSocket = nullptr;
|
||||
QDBusInterface *mprisInterface;
|
||||
QString connectedDeviceMacAddress;
|
||||
};
|
||||
109
linux/BluetoothHandler.cpp
Normal file
109
linux/BluetoothHandler.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "BluetoothHandler.h"
|
||||
#include "PacketDefinitions.h"
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_LOGGING_CATEGORY(bluetoothHandler, "bluetoothHandler")
|
||||
|
||||
#define LOG_INFO(msg) qCInfo(bluetoothHandler) << "\033[32m" << msg << "\033[0m"
|
||||
#define LOG_WARN(msg) qCWarning(bluetoothHandler) << "\033[33m" << msg << "\033[0m"
|
||||
#define LOG_ERROR(msg) qCCritical(bluetoothHandler) << "\033[31m" << msg << "\033[0m"
|
||||
#define LOG_DEBUG(msg) qCDebug(bluetoothHandler) << "\033[34m" << msg << "\033[0m"
|
||||
|
||||
BluetoothHandler::BluetoothHandler() {
|
||||
discoveryAgent = new QBluetoothDeviceDiscoveryAgent();
|
||||
discoveryAgent->setLowEnergyDiscoveryTimeout(5000);
|
||||
|
||||
connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothHandler::onDeviceDiscovered);
|
||||
connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothHandler::onDiscoveryFinished);
|
||||
discoveryAgent->start();
|
||||
LOG_INFO("BluetoothHandler initialized and started device discovery");
|
||||
}
|
||||
|
||||
void BluetoothHandler::connectToDevice(const QBluetoothDeviceInfo &device) {
|
||||
if (socket && socket->isOpen() && socket->peerAddress() == device.address()) {
|
||||
LOG_INFO("Already connected to the device: " << device.name());
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO("Connecting to device: " << device.name());
|
||||
QBluetoothSocket *localSocket = new QBluetoothSocket(QBluetoothServiceInfo::L2capProtocol);
|
||||
connect(localSocket, &QBluetoothSocket::connected, this, [this, localSocket]() {
|
||||
LOG_INFO("Connected to device, sending initial packets");
|
||||
discoveryAgent->stop();
|
||||
|
||||
QByteArray handshakePacket = QByteArray::fromHex("00000400010002000000000000000000");
|
||||
QByteArray setSpecificFeaturesPacket = QByteArray::fromHex("040004004d00ff00000000000000");
|
||||
QByteArray requestNotificationsPacket = QByteArray::fromHex("040004000f00ffffffffff");
|
||||
|
||||
qint64 bytesWritten = localSocket->write(handshakePacket);
|
||||
LOG_DEBUG("Handshake packet written: " << handshakePacket.toHex() << ", bytes written: " << bytesWritten);
|
||||
|
||||
QByteArray airpodsConnectedPacket = QByteArray::fromHex("000400010001");
|
||||
phoneSocket->write(airpodsConnectedPacket);
|
||||
LOG_DEBUG("AIRPODS_CONNECTED packet written: " << airpodsConnectedPacket.toHex());
|
||||
|
||||
connect(localSocket, &QBluetoothSocket::bytesWritten, this, [this, localSocket, setSpecificFeaturesPacket, requestNotificationsPacket](qint64 bytes) {
|
||||
LOG_INFO("Bytes written: " << bytes);
|
||||
if (bytes > 0) {
|
||||
static int step = 0;
|
||||
switch (step) {
|
||||
case 0:
|
||||
localSocket->write(setSpecificFeaturesPacket);
|
||||
LOG_DEBUG("Set specific features packet written: " << setSpecificFeaturesPacket.toHex());
|
||||
step++;
|
||||
break;
|
||||
case 1:
|
||||
localSocket->write(requestNotificationsPacket);
|
||||
LOG_DEBUG("Request notifications packet written: " << requestNotificationsPacket.toHex());
|
||||
step++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(localSocket, &QBluetoothSocket::readyRead, this, [this, localSocket]() {
|
||||
QByteArray data = localSocket->readAll();
|
||||
LOG_DEBUG("Data received: " << data.toHex());
|
||||
parseData(data);
|
||||
relayPacketToPhone(data);
|
||||
});
|
||||
});
|
||||
|
||||
connect(localSocket, QOverload<QBluetoothSocket::SocketError>::of(&QBluetoothSocket::errorOccurred), this, [this, localSocket](QBluetoothSocket::SocketError error) {
|
||||
LOG_ERROR("Socket error: " << error << ", " << localSocket->errorString());
|
||||
});
|
||||
|
||||
localSocket->connectToService(device.address(), QBluetoothUuid("74ec2172-0bad-4d01-8f77-997b2be0722a"));
|
||||
socket = localSocket;
|
||||
connectedDeviceMacAddress = device.address().toString().replace(":", "_");
|
||||
}
|
||||
|
||||
void BluetoothHandler::parseData(const QByteArray &data) {
|
||||
LOG_DEBUG("Parsing data: " << data.toHex() << "Size: " << data.size());
|
||||
if (data.size() == 11 && data.startsWith(QByteArray::fromHex("0400040009000D"))) {
|
||||
int mode = data[7] - 1;
|
||||
LOG_INFO("Noise control mode: " << mode);
|
||||
if (mode >= 0 && mode <= 3) {
|
||||
emit noiseControlModeChanged(mode);
|
||||
} else {
|
||||
LOG_ERROR("Invalid noise control mode value received: " << mode);
|
||||
}
|
||||
} else if (data.size() == 8 && data.startsWith(QByteArray::fromHex("040004000600"))) {
|
||||
bool primaryInEar = data[6] == 0x00;
|
||||
bool secondaryInEar = data[7] == 0x00;
|
||||
QString earDetectionStatus = QString("Primary: %1, Secondary: %2")
|
||||
.arg(primaryInEar ? "In Ear" : "Out of Ear")
|
||||
.arg(secondaryInEar ? "In Ear" : "Out of Ear");
|
||||
LOG_INFO("Ear detection status: " << earDetectionStatus);
|
||||
emit earDetectionStatusChanged(earDetectionStatus);
|
||||
} else if (data.size() == 22 && data.startsWith(QByteArray::fromHex("040004000400"))) {
|
||||
int leftLevel = data[9];
|
||||
int rightLevel = data[14];
|
||||
int caseLevel = data[19];
|
||||
QString batteryStatus = QString("Left: %1%, Right: %2%, Case: %3%")
|
||||
.arg(leftLevel)
|
||||
.arg(rightLevel)
|
||||
.arg(caseLevel);
|
||||
LOG_INFO("Battery status: " << batteryStatus);
|
||||
emit batteryStatusChanged(batteryStatus);
|
||||
} else if (data.size() == 10 &&
|
||||
23
linux/BluetoothHandler.h
Normal file
23
linux/BluetoothHandler.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <QBluetoothDeviceInfo>
|
||||
#include <QBluetoothSocket>
|
||||
#include <QBluetoothDeviceDiscoveryAgent>
|
||||
|
||||
class BluetoothHandler : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BluetoothHandler();
|
||||
void connectToDevice(const QBluetoothDeviceInfo &device);
|
||||
void parseData(const QByteArray &data);
|
||||
|
||||
signals:
|
||||
void noiseControlModeChanged(int mode);
|
||||
void earDetectionStatusChanged(const QString &status);
|
||||
void batteryStatusChanged(const QString &status);
|
||||
|
||||
private:
|
||||
QBluetoothSocket *socket = nullptr;
|
||||
QBluetoothDeviceDiscoveryAgent *discoveryAgent;
|
||||
};
|
||||
@@ -10,6 +10,9 @@ qt_standard_project_setup(REQUIRES 6.5)
|
||||
|
||||
qt_add_executable(applinux
|
||||
main.cpp
|
||||
AirPodsTrayApp.cpp
|
||||
BluetoothHandler.cpp
|
||||
PacketDefinitions.cpp
|
||||
)
|
||||
|
||||
qt_add_qml_module(applinux
|
||||
|
||||
Reference in New Issue
Block a user