bluez5: handle XAPL battery level per Apple Guidelines

Corrects the handling of AT+XAPL Apple extensions to send
`+XAPL=iPhone,2` instead of `+XAPL: iPhone,2` based on Apple's
documentation.

Replaces magic numbers with enum values.

[Accessory Design Guidelines](https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf)
This commit is contained in:
Zsombor Welker 2021-08-12 21:45:22 +02:00
parent a1777d00e3
commit f5850af4d8
2 changed files with 27 additions and 6 deletions

View file

@ -656,6 +656,10 @@ static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
unsigned int selected_codec;
unsigned int indicator;
unsigned int indicator_value;
int xapl_vendor;
int xapl_product;
int xapl_version;
int xapl_features;
if (sscanf(buf, "AT+BRSF=%u", &features) == 1) {
unsigned int ag_features = SPA_BT_HFP_AG_FEATURE_NONE;
@ -838,9 +842,11 @@ static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
} else {
spa_log_warn(backend->log, NAME": unknown HF indicator: %u", indicator);
}
} else if (strncmp(buf, "AT+XAPL=", 8) == 0) {
// We expect battery status only (bitmask 10)
rfcomm_send_reply(rfcomm, "+XAPL: iPhone,2");
} else if (sscanf(buf, "AT+XAPL=%04x-%04x-%04x,%u", &xapl_vendor, &xapl_product, &xapl_version, &xapl_features) == 4) {
if (xapl_features & SPA_BT_HFP_HF_XAPL_FEATURE_BATTERY_REPORTING) {
/* claim, that we support battery status reports */
rfcomm_send_reply(rfcomm, "+XAPL=iPhone,%u", SPA_BT_HFP_HF_XAPL_FEATURE_BATTERY_REPORTING);
}
rfcomm_send_reply(rfcomm, "OK");
} else if (sscanf(buf, "AT+IPHONEACCEV=%u", &len) == 1) {
unsigned int i;
@ -864,7 +870,7 @@ static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
if (sscanf(buf, "%d", &v) != 1)
return false;
if (k == SPA_BT_HFP_HF_IPHONEACCEV_KEY_BATTERY) {
if (k == SPA_BT_HFP_HF_IPHONEACCEV_KEY_BATTERY_LEVEL) {
// Battery level is reported in range of 0-9, convert to 0-100%
uint8_t level = (SPA_CLAMP(v, 0, 9) + 1) * 10;
spa_log_debug(backend->log, NAME": battery level: %d%%", (int)level);

View file

@ -60,8 +60,6 @@ extern "C" {
#define PIPEWIRE_BATTERY_PROVIDER "/org/freedesktop/pipewire/battery"
#define SPA_BT_HFP_HF_IPHONEACCEV_KEY_BATTERY 1
#define MIN_LATENCY 512
#define MAX_LATENCY 1024
@ -262,6 +260,23 @@ enum spa_bt_hfp_hf_indicator {
SPA_BT_HFP_HF_INDICATOR_BATTERY_LEVEL = 2,
};
/* HFP Command AT+IPHONEACCEV
* https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf */
enum spa_bt_hfp_hf_iphoneaccev_keys {
SPA_BT_HFP_HF_IPHONEACCEV_KEY_BATTERY_LEVEL = 1,
SPA_BT_HFP_HF_IPHONEACCEV_KEY_DOCK_STATE = 2,
};
/* HFP Command AT+XAPL
* https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf
* Bits 0, 5 and above are reserved. */
enum spa_bt_hfp_hf_xapl_features {
SPA_BT_HFP_HF_XAPL_FEATURE_BATTERY_REPORTING = (1 << 1),
SPA_BT_HFP_HF_XAPL_FEATURE_DOCKED_OR_POWERED = (1 << 2),
SPA_BT_HFP_HF_XAPL_FEATURE_SIRI_STATUS_REPORTING = (1 << 3),
SPA_BT_HFP_HF_XAPL_FEATURE_NOISE_REDUCTION_REPORTING = (1 << 4),
};
enum spa_bt_hfp_sdp_hf_features {
SPA_BT_HFP_SDP_HF_FEATURE_NONE = (0),
SPA_BT_HFP_SDP_HF_FEATURE_ECNR = (1 << 0),