mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-02-01 07:39:11 +00:00
127 lines
3.3 KiB
C++
127 lines
3.3 KiB
C++
#include <QByteArray>
|
|
#include <QMap>
|
|
#include <QString>
|
|
|
|
#include "airpods_packets.h"
|
|
|
|
class Battery
|
|
{
|
|
public:
|
|
// Enum for AirPods components
|
|
enum class Component
|
|
{
|
|
Right = 0x02,
|
|
Left = 0x04,
|
|
Case = 0x08,
|
|
};
|
|
|
|
enum class BatteryStatus
|
|
{
|
|
Unknown = 0,
|
|
Charging = 0x01,
|
|
Discharging = 0x02,
|
|
Disconnected = 0x04,
|
|
};
|
|
|
|
// Struct to hold battery level and status
|
|
struct BatteryState
|
|
{
|
|
int level = 0; // Battery level (0-100), -1 if unknown
|
|
BatteryStatus status = BatteryStatus::Unknown;
|
|
};
|
|
|
|
// Constructor: Initialize all components to unknown state
|
|
Battery()
|
|
{
|
|
states[Component::Left] = {};
|
|
states[Component::Right] = {};
|
|
states[Component::Case] = {};
|
|
}
|
|
|
|
// Parse the battery status packet
|
|
bool parsePacket(const QByteArray &packet)
|
|
{
|
|
if (!packet.startsWith(AirPodsPackets::Parse::BATTERY_STATUS))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Get battery count (number of components)
|
|
quint8 batteryCount = static_cast<quint8>(packet[6]);
|
|
if (batteryCount > 3 || packet.size() != 7 + 5 * batteryCount)
|
|
{
|
|
return false; // Invalid count or size mismatch
|
|
}
|
|
|
|
// Copy current states; only included components will be updated
|
|
QMap<Component, BatteryState> newStates = states;
|
|
|
|
// Parse each component
|
|
for (quint8 i = 0; i < batteryCount; ++i)
|
|
{
|
|
int offset = 7 + (5 * i);
|
|
quint8 type = static_cast<quint8>(packet[offset]);
|
|
|
|
// Verify spacer and end bytes
|
|
if (static_cast<quint8>(packet[offset + 1]) != 0x01 ||
|
|
static_cast<quint8>(packet[offset + 4]) != 0x01)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Map byte value to component
|
|
Component comp = static_cast<Component>(type);
|
|
|
|
// Extract level and status
|
|
int level = static_cast<quint8>(packet[offset + 2]);
|
|
auto status = static_cast<BatteryStatus>(packet[offset + 3]);
|
|
|
|
// Update the state for this component
|
|
newStates[comp] = {level, status};
|
|
}
|
|
|
|
// Apply updates; unmentioned components retain old states
|
|
states = newStates;
|
|
return true;
|
|
}
|
|
|
|
// Get the raw state for a component
|
|
BatteryState getState(Component comp) const
|
|
{
|
|
return states.value(comp, {});
|
|
}
|
|
|
|
// Get a formatted status string including charging state
|
|
QString getComponentStatus(Component comp) const
|
|
{
|
|
BatteryState state = getState(comp);
|
|
if (state.level == -1)
|
|
{
|
|
return "Unknown";
|
|
}
|
|
|
|
QString statusStr;
|
|
switch (state.status)
|
|
{
|
|
case BatteryStatus::Unknown:
|
|
statusStr = "Unknown";
|
|
break;
|
|
case BatteryStatus::Charging:
|
|
statusStr = "Charging";
|
|
break;
|
|
case BatteryStatus::Discharging:
|
|
statusStr = "Discharging";
|
|
break;
|
|
case BatteryStatus::Disconnected:
|
|
statusStr = "Disconnected";
|
|
break;
|
|
default:
|
|
statusStr = "Invalid";
|
|
break;
|
|
}
|
|
return QString("%1% (%2)").arg(state.level).arg(statusStr);
|
|
}
|
|
|
|
private:
|
|
QMap<Component, BatteryState> states;
|
|
}; |