From 640f34d8e24059104347b49dab173142a2cd5e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Danis?= Date: Tue, 9 Feb 2021 17:58:07 +0100 Subject: [PATCH] bluez: Fix HSP command parser The HSP command parser should not reply, with 'OK' or 'ERROR', to result codes from the remote AG. Split the command parser in AG and HS part. --- spa/plugins/bluez5/backend-native.c | 48 +++++++++++++++++++---------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/spa/plugins/bluez5/backend-native.c b/spa/plugins/bluez5/backend-native.c index a6e8b6f9c..a76511a68 100644 --- a/spa/plugins/bluez5/backend-native.c +++ b/spa/plugins/bluez5/backend-native.c @@ -167,26 +167,18 @@ static void rfcomm_send_reply(struct spa_source *source, char *data) } #ifdef HAVE_BLUEZ_5_BACKEND_HSP_NATIVE -static bool rfcomm_hsp(struct spa_source *source, char* buf) +static bool rfcomm_hsp_ag(struct spa_source *source, char* buf) { unsigned int gain, dummy; - /* There are only four HSP AT commands: - * AT+VGS=value: value between 0 and 15, sent by the HS to AG to set the speaker gain. - * +VGS=value is sent by AG to HS as a response to an AT+VGS command or when the gain - * is changed on the AG side. - * AT+VGM=value: value between 0 and 15, sent by the HS to AG to set the microphone gain. - * +VGM=value is sent by AG to HS as a response to an AT+VGM command or when the gain - * is changed on the AG side. - * AT+CKPD=200: Sent by HS when headset button is pressed. - * RING: Sent by AG to HS to notify of an incoming call. It can safely be ignored because - * it does not expect a reply. */ - if (sscanf(buf, "AT+VGS=%d", &gain) == 1 || - sscanf(buf, "\r\n+VGM=%d\r\n", &gain) == 1) { + /* There are only three HSP AT commands: + * AT+VGS=value: value between 0 and 15, sent by the HS to AG to set the speaker gain. + * AT+VGM=value: value between 0 and 15, sent by the HS to AG to set the microphone gain. + * AT+CKPD=200: Sent by HS when headset button is pressed. */ + if (sscanf(buf, "AT+VGS=%d", &gain) == 1) { /* t->speaker_gain = gain; */ rfcomm_send_reply(source, "OK"); - } else if (sscanf(buf, "AT+VGM=%d", &gain) == 1 || - sscanf(buf, "\r\n+VGS=%d\r\n", &gain) == 1) { + } else if (sscanf(buf, "AT+VGM=%d", &gain) == 1) { /* t->microphone_gain = gain; */ rfcomm_send_reply(source, "OK"); } else if (sscanf(buf, "AT+CKPD=%d", &dummy) == 1) { @@ -197,6 +189,26 @@ static bool rfcomm_hsp(struct spa_source *source, char* buf) return true; } + +static bool rfcomm_hsp_hs(struct spa_source *source, char* buf) +{ + unsigned int gain; + + /* There are only three HSP AT result codes: + * +VGS=value: value between 0 and 15, sent by AG to HS as a response to an AT+VGS command + * or when the gain is changed on the AG side. + * +VGM=value: value between 0 and 15, sent by AG to HS as a response to an AT+VGM command + * or when the gain is changed on the AG side. + * RING: Sent by AG to HS to notify of an incoming call. It can safely be ignored because + * it does not expect a reply. */ + if (sscanf(buf, "\r\n+VGS=%d\r\n", &gain) == 1) { + /* t->microphone_gain = gain; */ + } else if (sscanf(buf, "\r\n+VGM=%d\r\n", &gain) == 1) { + /* t->speaker_gain = gain; */ + } + + return true; +} #endif #ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE @@ -424,8 +436,10 @@ static void rfcomm_event(struct spa_source *source) spa_log_debug(backend->log, NAME": RFCOMM << %s", buf); #ifdef HAVE_BLUEZ_5_BACKEND_HSP_NATIVE - if ((rfcomm->profile == SPA_BT_PROFILE_HSP_AG) || (rfcomm->profile == SPA_BT_PROFILE_HSP_HS)) - res = rfcomm_hsp(source, buf); + if (rfcomm->profile == SPA_BT_PROFILE_HSP_HS) + res = rfcomm_hsp_ag(source, buf); + else if (rfcomm->profile == SPA_BT_PROFILE_HSP_AG) + res = rfcomm_hsp_hs(source, buf); #endif #ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE if (rfcomm->profile == SPA_BT_PROFILE_HFP_HF)