mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
bluez5: backend-native: report HFP AG battery indicator to UPower
This commit is contained in:
parent
bac7b10226
commit
79b95e083a
1 changed files with 52 additions and 4 deletions
|
|
@ -66,6 +66,8 @@ static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.native");
|
||||||
#define INTERNATIONAL_NUMBER 145
|
#define INTERNATIONAL_NUMBER 145
|
||||||
#define NATIONAL_NUMBER 129
|
#define NATIONAL_NUMBER 129
|
||||||
|
|
||||||
|
#define MAX_HF_INDICATORS 16
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HFP_AG_INITIAL_CODEC_SETUP_NONE = 0,
|
HFP_AG_INITIAL_CODEC_SETUP_NONE = 0,
|
||||||
HFP_AG_INITIAL_CODEC_SETUP_SEND,
|
HFP_AG_INITIAL_CODEC_SETUP_SEND,
|
||||||
|
|
@ -183,6 +185,7 @@ struct rfcomm {
|
||||||
enum hsp_hs_state hs_state;
|
enum hsp_hs_state hs_state;
|
||||||
unsigned int codec;
|
unsigned int codec;
|
||||||
uint32_t cind_enabled_indicators;
|
uint32_t cind_enabled_indicators;
|
||||||
|
char *hf_indicators[MAX_HF_INDICATORS];
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -271,6 +274,11 @@ static void volume_sync_stop_timer(struct rfcomm *rfcomm);
|
||||||
static void rfcomm_free(struct rfcomm *rfcomm)
|
static void rfcomm_free(struct rfcomm *rfcomm)
|
||||||
{
|
{
|
||||||
codec_switch_stop_timer(rfcomm);
|
codec_switch_stop_timer(rfcomm);
|
||||||
|
for (int i = 0; i < MAX_HF_INDICATORS; i++) {
|
||||||
|
if (rfcomm->hf_indicators[i]) {
|
||||||
|
free(rfcomm->hf_indicators[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
spa_list_remove(&rfcomm->link);
|
spa_list_remove(&rfcomm->link);
|
||||||
if (rfcomm->path)
|
if (rfcomm->path)
|
||||||
free(rfcomm->path);
|
free(rfcomm->path);
|
||||||
|
|
@ -1148,9 +1156,7 @@ next_indicator:
|
||||||
static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* buf)
|
static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* buf)
|
||||||
{
|
{
|
||||||
struct impl *backend = rfcomm->backend;
|
struct impl *backend = rfcomm->backend;
|
||||||
unsigned int features;
|
unsigned int features, gain, selected_codec, indicator, value;
|
||||||
unsigned int gain;
|
|
||||||
unsigned int selected_codec;
|
|
||||||
char* token;
|
char* token;
|
||||||
|
|
||||||
while ((token = strsep(&buf, "\r\n"))) {
|
while ((token = strsep(&buf, "\r\n"))) {
|
||||||
|
|
@ -1195,6 +1201,47 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* buf)
|
||||||
} else {
|
} else {
|
||||||
spa_log_debug(backend->log, "RFCOMM receive unsupported VGS gain: %s", token);
|
spa_log_debug(backend->log, "RFCOMM receive unsupported VGS gain: %s", token);
|
||||||
}
|
}
|
||||||
|
} else if (spa_strstartswith(token, "+CIND: (")) {
|
||||||
|
uint8_t i = 1;
|
||||||
|
while (strstr(token, "\"")) {
|
||||||
|
token += strcspn(token, "\"") + 1;
|
||||||
|
token[strcspn(token, "\"")] = 0;
|
||||||
|
rfcomm->hf_indicators[i] = strdup(token);
|
||||||
|
token += strcspn(token, "\"") + 1;
|
||||||
|
i++;
|
||||||
|
if (i == MAX_HF_INDICATORS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (spa_strstartswith(token, "+CIND: ")) {
|
||||||
|
token[strcspn(token, "\r")] = 0;
|
||||||
|
token[strcspn(token, "\n")] = 0;
|
||||||
|
token += strlen("+CIND: ");
|
||||||
|
uint8_t i = 1;
|
||||||
|
while (strlen(token)) {
|
||||||
|
if (i >= MAX_HF_INDICATORS || !rfcomm->hf_indicators[i]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
token[strcspn(token, ",")] = 0;
|
||||||
|
spa_log_info(backend->log, "AG indicator state: %s = %i", rfcomm->hf_indicators[i], atoi(token));
|
||||||
|
|
||||||
|
if (spa_streq(rfcomm->hf_indicators[i], "battchg")) {
|
||||||
|
spa_bt_device_report_battery_level(rfcomm->device, atoi(token) * 100 / 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
token += strcspn(token, "\0") + 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else if (sscanf(token, "+CIEV: %u,%u", &indicator, &value) == 2) {
|
||||||
|
if (indicator >= MAX_HF_INDICATORS || !rfcomm->hf_indicators[indicator]) {
|
||||||
|
spa_log_warn(backend->log, "indicator %u has not been registered, ignoring", indicator);
|
||||||
|
} else {
|
||||||
|
spa_log_info(backend->log, "AG indicator update: %s = %u", rfcomm->hf_indicators[indicator], value);
|
||||||
|
|
||||||
|
if (spa_streq(rfcomm->hf_indicators[indicator], "battchg")) {
|
||||||
|
spa_bt_device_report_battery_level(rfcomm->device, value * 100 / 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (spa_strstartswith(token, "OK")) {
|
} else if (spa_strstartswith(token, "OK")) {
|
||||||
switch(rfcomm->hf_state) {
|
switch(rfcomm->hf_state) {
|
||||||
case hfp_hf_brsf:
|
case hfp_hf_brsf:
|
||||||
|
|
@ -1215,7 +1262,7 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* buf)
|
||||||
rfcomm->hf_state = hfp_hf_cind2;
|
rfcomm->hf_state = hfp_hf_cind2;
|
||||||
break;
|
break;
|
||||||
case hfp_hf_cind2:
|
case hfp_hf_cind2:
|
||||||
rfcomm_send_cmd(rfcomm, "AT+CMER=3,0,0,0");
|
rfcomm_send_cmd(rfcomm, "AT+CMER=3,0,0,1");
|
||||||
rfcomm->hf_state = hfp_hf_cmer;
|
rfcomm->hf_state = hfp_hf_cmer;
|
||||||
break;
|
break;
|
||||||
case hfp_hf_cmer:
|
case hfp_hf_cmer:
|
||||||
|
|
@ -2073,6 +2120,7 @@ static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessag
|
||||||
rfcomm->source.rmask = 0;
|
rfcomm->source.rmask = 0;
|
||||||
/* By default all indicators are enabled */
|
/* By default all indicators are enabled */
|
||||||
rfcomm->cind_enabled_indicators = 0xFFFFFFFF;
|
rfcomm->cind_enabled_indicators = 0xFFFFFFFF;
|
||||||
|
memset(rfcomm->hf_indicators, 0, sizeof rfcomm->hf_indicators);
|
||||||
|
|
||||||
for (int i = 0; i < SPA_BT_VOLUME_ID_TERM; ++i) {
|
for (int i = 0; i < SPA_BT_VOLUME_ID_TERM; ++i) {
|
||||||
if (rfcomm->profile & SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY)
|
if (rfcomm->profile & SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue