mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-01-31 23:29:10 +00:00
[Linux] Implement renaming airpods (#88)
* [Linux] Implement rename airpods * [Linux] Get airpods name from airpods metadata * [Linux] Rename AirPods: Ui improvements --------- Co-authored-by: Tim Gromeyer <tim.gromeyer@trans4mation.de>
This commit is contained in:
110
linux/main.cpp
110
linux/main.cpp
@@ -20,6 +20,7 @@ class AirPodsTrayApp : public QObject {
|
||||
Q_PROPERTY(bool conversationalAwareness READ conversationalAwareness WRITE setConversationalAwareness NOTIFY conversationalAwarenessChanged)
|
||||
Q_PROPERTY(int adaptiveNoiseLevel READ adaptiveNoiseLevel WRITE setAdaptiveNoiseLevel NOTIFY adaptiveNoiseLevelChanged)
|
||||
Q_PROPERTY(bool adaptiveModeActive READ adaptiveModeActive NOTIFY noiseControlModeChanged)
|
||||
Q_PROPERTY(QString deviceName READ deviceName NOTIFY deviceNameChanged)
|
||||
|
||||
public:
|
||||
AirPodsTrayApp(bool debugMode) : debugMode(debugMode) {
|
||||
@@ -100,6 +101,7 @@ public:
|
||||
bool conversationalAwareness() const { return m_conversationalAwareness; }
|
||||
bool adaptiveModeActive() const { return m_noiseControlMode == NoiseControlMode::Adaptive; }
|
||||
int adaptiveNoiseLevel() const { return m_adaptiveNoiseLevel; }
|
||||
QString deviceName() const { return m_deviceName; }
|
||||
|
||||
private:
|
||||
bool debugMode;
|
||||
@@ -272,6 +274,37 @@ public slots:
|
||||
}
|
||||
}
|
||||
|
||||
void renameAirPods(const QString &newName)
|
||||
{
|
||||
if (newName.isEmpty())
|
||||
{
|
||||
LOG_WARN("Cannot set empty name");
|
||||
return;
|
||||
}
|
||||
if (newName.size() > 32)
|
||||
{
|
||||
LOG_WARN("Name is too long, must be 32 characters or less");
|
||||
return;
|
||||
}
|
||||
if (newName == m_deviceName)
|
||||
{
|
||||
LOG_INFO("Name is already set to: " << newName);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray packet = AirPodsPackets::Rename::getPacket(newName);
|
||||
if (writePacketToSocket(packet, "Rename packet written: "))
|
||||
{
|
||||
LOG_INFO("Sent rename command for new name: " << newName);
|
||||
m_deviceName = newName;
|
||||
emit deviceNameChanged(newName);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Failed to send rename command: socket not open");
|
||||
}
|
||||
}
|
||||
|
||||
bool writePacketToSocket(const QByteArray &packet, const QString &logMessage)
|
||||
{
|
||||
if (socket && socket->isOpen())
|
||||
@@ -363,6 +396,77 @@ private slots:
|
||||
}
|
||||
}
|
||||
|
||||
void parseMetadata(const QByteArray &data)
|
||||
{
|
||||
// Verify the data starts with the METADATA header
|
||||
if (!data.startsWith(AirPodsPackets::Parse::METADATA))
|
||||
{
|
||||
LOG_ERROR("Invalid metadata packet: Incorrect header");
|
||||
return;
|
||||
}
|
||||
|
||||
int pos = AirPodsPackets::Parse::METADATA.size(); // Start after the header
|
||||
|
||||
// Check if there is enough data to skip the initial bytes (based on example structure)
|
||||
if (data.size() < pos + 6)
|
||||
{
|
||||
LOG_ERROR("Metadata packet too short to parse initial bytes");
|
||||
return;
|
||||
}
|
||||
pos += 6; // Skip 6 bytes after the header as per example structure
|
||||
|
||||
auto extractString = [&data, &pos]() -> QString
|
||||
{
|
||||
if (pos >= data.size())
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
int start = pos;
|
||||
while (pos < data.size() && data.at(pos) != '\0')
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
QString str = QString::fromUtf8(data.mid(start, pos - start));
|
||||
if (pos < data.size())
|
||||
{
|
||||
++pos; // Move past the null terminator
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
m_deviceName = extractString();
|
||||
QString modelNumber = extractString();
|
||||
QString manufacturer = extractString();
|
||||
QString hardwareVersion = extractString();
|
||||
QString firmwareVersion = extractString();
|
||||
QString firmwareVersion2 = extractString();
|
||||
QString softwareVersion = extractString();
|
||||
QString appIdentifier = extractString();
|
||||
QString serialNumber1 = extractString();
|
||||
QString serialNumber2 = extractString();
|
||||
QString unknownNumeric = extractString();
|
||||
QString unknownHash = extractString();
|
||||
QString trailingByte = extractString();
|
||||
|
||||
emit deviceNameChanged(m_deviceName);
|
||||
|
||||
// Log extracted metadata
|
||||
LOG_INFO("Parsed AirPods metadata:");
|
||||
LOG_INFO("Device Name: " << m_deviceName);
|
||||
LOG_INFO("Model Number: " << modelNumber);
|
||||
LOG_INFO("Manufacturer: " << manufacturer);
|
||||
LOG_INFO("Hardware Version: " << hardwareVersion);
|
||||
LOG_INFO("Firmware Version: " << firmwareVersion);
|
||||
LOG_INFO("Firmware Version2: " << firmwareVersion2);
|
||||
LOG_INFO("Software Version: " << softwareVersion);
|
||||
LOG_INFO("App Identifier: " << appIdentifier);
|
||||
LOG_INFO("Serial Number 1: " << serialNumber1);
|
||||
LOG_INFO("Serial Number 2: " << serialNumber2);
|
||||
LOG_INFO("Unknown Numeric: " << unknownNumeric);
|
||||
LOG_INFO("Unknown Hash: " << unknownHash);
|
||||
LOG_INFO("Trailing Byte: " << trailingByte);
|
||||
}
|
||||
|
||||
void connectToDevice(const QBluetoothDeviceInfo &device) {
|
||||
if (socket && socket->isOpen() && socket->peerAddress() == device.address()) {
|
||||
LOG_INFO("Already connected to the device: " << device.name());
|
||||
@@ -490,6 +594,10 @@ private slots:
|
||||
LOG_INFO("Received conversational awareness data");
|
||||
mediaController->handleConversationalAwareness(data);
|
||||
}
|
||||
else if (data.startsWith(AirPodsPackets::Parse::METADATA))
|
||||
{
|
||||
parseMetadata(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("Unrecognized packet format: " << data.toHex());
|
||||
@@ -714,6 +822,7 @@ signals:
|
||||
void batteryStatusChanged(const QString &status);
|
||||
void conversationalAwarenessChanged(bool enabled);
|
||||
void adaptiveNoiseLevelChanged(int level);
|
||||
void deviceNameChanged(const QString &name);
|
||||
|
||||
private:
|
||||
QSystemTrayIcon *trayIcon;
|
||||
@@ -733,6 +842,7 @@ private:
|
||||
NoiseControlMode m_noiseControlMode = NoiseControlMode::Off;
|
||||
bool m_conversationalAwareness = false;
|
||||
int m_adaptiveNoiseLevel = 50;
|
||||
QString m_deviceName;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
Reference in New Issue
Block a user