try to add some cross-device stuff

This commit is contained in:
Kavish Devar
2025-01-20 04:13:18 +05:30
parent 7cac2b037f
commit 7a06f3055c
6 changed files with 178 additions and 111 deletions

View File

@@ -1,74 +0,0 @@
import bluetooth
import time
import threading
# Bluetooth MAC address of the target device
TARGET_MAC = "22:22:F5:BB:1C:A0" # Replace with the actual MAC address
UUID = "1abbb9a4-10e4-4000-a75c-8953c5471342"
# Define packets
PACKETS = {
"AIRPODS_CONNECTED": b"\x00\x01\x00\x01",
"AIRPODS_DISCONNECTED": b"\x00\x01\x00\x00",
"REQUEST_BATTERY_BYTES": b"\x00\x02\x00\x01",
"REQUEST_ANC_BYTES": b"\x00\x02\x00\x02",
"REQUEST_DISCONNECT": b"\x00\x02\x00\x00"
}
def send_packet(sock, packet_name):
if packet_name in PACKETS:
packet = PACKETS[packet_name]
sock.send(packet)
print(f"Sent packet: {packet_name}")
else:
print(f"Packet {packet_name} not defined.")
def listen_for_packets(sock):
try:
while True:
data = sock.recv(1024)
if data:
print(f"Received packet: {data}")
except Exception as e:
print(f"Error receiving data: {e}")
def main():
# Discover services to find the channel using the UUID
services = bluetooth.find_service(address=TARGET_MAC, uuid=UUID)
if len(services) == 0:
print(f"Could not find services for UUID {UUID}")
return
# Use the first service found
service = services[0]
port = service["port"]
name = service["name"]
host = service["host"]
print(f"Connecting to \"{name}\" on {host}, port {port}")
# Create a Bluetooth socket
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect((host, port))
print(f"Connected to {TARGET_MAC} on port {port}")
# Start listening for packets in a background thread
listener_thread = threading.Thread(target=listen_for_packets, args=(sock,))
listener_thread.daemon = True
listener_thread.start()
try:
while True:
packet_name = input("Enter packet name to send (or 'exit' to quit): ")
if packet_name.lower() == "exit":
break
send_packet(sock, packet_name)
time.sleep(1)
except Exception as e:
print(f"Error: {e}")
finally:
sock.close()
print("Connection closed.")
if __name__ == "__main__":
main()

View File

@@ -37,6 +37,8 @@ Q_LOGGING_CATEGORY(airpodsApp, "airpodsApp")
#define LOG_ERROR(msg) qCCritical(airpodsApp) << "\033[31m" << msg << "\033[0m"
#define LOG_DEBUG(msg) qCDebug(airpodsApp) << "\033[34m" << msg << "\033[0m"
#define PHONE_MAC_ADDRESS "22:22:F5:BB:1C:A0"
class AirPodsTrayApp : public QObject {
Q_OBJECT
@@ -104,6 +106,7 @@ public:
}
}
initializeMprisInterface();
connect(phoneSocket, &QBluetoothSocket::readyRead, this, &AirPodsTrayApp::onPhoneDataReceived);
}
public slots:
@@ -340,6 +343,10 @@ public slots:
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) {
@@ -363,6 +370,7 @@ public slots:
QByteArray data = localSocket->readAll();
LOG_DEBUG("Data received: " << data.toHex());
parseData(data);
relayPacketToPhone(data);
});
});
@@ -403,6 +411,7 @@ public slots:
.arg(caseLevel);
LOG_INFO("Battery status: " << batteryStatus);
emit batteryStatusChanged(batteryStatus);
relayPacketToPhone(data);
} else if (data.size() == 10 && data.startsWith(QByteArray::fromHex("040004004B00020001"))) {
LOG_INFO("Received conversational awareness data");
@@ -471,6 +480,67 @@ public slots:
} else {
LOG_WARN("No active MPRIS media players found");
}
connectToPhone();
}
void connectToPhone() {
if (phoneSocket && phoneSocket->isOpen()) {
LOG_INFO("Already connected to the phone");
return;
}
QBluetoothAddress phoneAddress(PHONE_MAC_ADDRESS);
phoneSocket = new QBluetoothSocket(QBluetoothServiceInfo::L2capProtocol);
connect(phoneSocket, &QBluetoothSocket::connected, this, [this]() {
LOG_INFO("Connected to phone");
});
connect(phoneSocket, QOverload<QBluetoothSocket::SocketError>::of(&QBluetoothSocket::errorOccurred), this, [this](QBluetoothSocket::SocketError error) {
LOG_ERROR("Phone socket error: " << error << ", " << phoneSocket->errorString());
});
phoneSocket->connectToService(phoneAddress, QBluetoothUuid("1abbb9a4-10e4-4000-a75c-8953c5471342"));
}
void relayPacketToPhone(const QByteArray &packet) {
if (phoneSocket && phoneSocket->isOpen()) {
QByteArray header = QByteArray::fromHex("00040001");
phoneSocket->write(header + packet);
LOG_DEBUG("Relayed packet to phone with header: " << (header + packet).toHex());
} else {
LOG_WARN("Phone socket is not open, cannot relay packet");
}
}
void handlePhonePacket(const QByteArray &packet) {
if (packet.startsWith(QByteArray::fromHex("00040001"))) {
QByteArray airpodsPacket = packet.mid(4); // Remove the header
if (socket && socket->isOpen()) {
socket->write(airpodsPacket);
LOG_DEBUG("Relayed packet to AirPods: " << airpodsPacket.toHex());
} else {
LOG_ERROR("Socket is not open, cannot relay packet to AirPods");
}
} else if (packet.startsWith(QByteArray::fromHex("00010001"))) {
LOG_INFO("AirPods connected");
// Handle AirPods connected
} else if (packet.startsWith(QByteArray::fromHex("00010000"))) {
LOG_INFO("AirPods disconnected");
// Handle AirPods disconnected
} else {
if (socket && socket->isOpen()) {
socket->write(packet);
LOG_DEBUG("Relayed packet to AirPods: " << packet.toHex());
} else {
LOG_ERROR("Socket is not open, cannot relay packet to AirPods");
}
}
}
void onPhoneDataReceived() {
QByteArray data = phoneSocket->readAll();
LOG_DEBUG("Data received from phone: " << data.toHex());
handlePhonePacket(data);
}
signals:
@@ -483,6 +553,7 @@ private:
QMenu *trayMenu;
QBluetoothDeviceDiscoveryAgent *discoveryAgent;
QBluetoothSocket *socket = nullptr;
QBluetoothSocket *phoneSocket = nullptr;
QDBusInterface *mprisInterface;
QString connectedDeviceMacAddress;
};