move files across computers

This commit is contained in:
Kavish Devar
2025-01-25 03:12:23 +05:30
parent a6d7bd704a
commit 5d364a662c
22 changed files with 714 additions and 321 deletions

53
linux/AirPodsTrayApp.h Normal file
View 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
View 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
View 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;
};

View File

@@ -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