From 046ce91c4b70d51bff95e147ad66f672d8431e1e Mon Sep 17 00:00:00 2001 From: "Igor V. Kovalenko" Date: Fri, 5 Mar 2021 14:40:37 +0300 Subject: [PATCH] bluetooth: correct rfcomm command and reply formatting The format of COMMAND line sent from HS to AG is COMMAND The format of RESPONSE line sent from AG to HS is RESPONSE Split rfcomm_write into rfcomm_write_command and rfcomm_write_response to handle line formatting correctly. Part-of: --- src/modules/bluetooth/backend-native.c | 49 +++++++++++++++++--------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c index 3ad67b6ed..d597f7c6e 100644 --- a/src/modules/bluetooth/backend-native.c +++ b/src/modules/bluetooth/backend-native.c @@ -139,20 +139,17 @@ static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_backend *backend, D return p; } -static void rfcomm_write(int fd, const char *fmt, ...) +static void rfcomm_fmt_write(int fd, const char* fmt_line, const char *fmt_command, va_list ap) { - va_list ap; size_t len; char buf[512]; char command[512]; - va_start(ap, fmt); - pa_vsnprintf(command, sizeof(command), fmt, ap); - va_end(ap); + pa_vsnprintf(command, sizeof(command), fmt_command, ap); pa_log_debug("RFCOMM >> %s", command); - len = pa_snprintf(buf, sizeof(buf), "\r\n%s\r\n", command); + len = pa_snprintf(buf, sizeof(buf), fmt_line, command); /* we ignore any errors, it's not critical and real errors should * be caught with the HANGUP and ERROR events handled above */ @@ -161,6 +158,26 @@ static void rfcomm_write(int fd, const char *fmt, ...) pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno)); } +/* The format of COMMAND line sent from HS to AG is COMMAND */ +static void rfcomm_write_command(int fd, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + rfcomm_fmt_write(fd, "%s\r", fmt, ap); + va_end(ap); +} + +/* The format of RESPONSE line sent from AG to HS is RESPONSE */ +static void rfcomm_write_response(int fd, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + rfcomm_fmt_write(fd, "\r\n%s\r\n", fmt, ap); + va_end(ap); +} + static int sco_do_connect(pa_bluetooth_transport *t) { pa_bluetooth_device *d = t->device; struct sockaddr_sco addr; @@ -424,12 +441,12 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf if (c->state == 0 && sscanf(buf, "AT+BRSF=%d", &val) == 1) { c->capabilities = val; pa_log_info("HFP capabilities returns 0x%x", val); - rfcomm_write(fd, "+BRSF: %d", hfp_features); + rfcomm_write_response(fd, "+BRSF: %d", hfp_features); c->state = 1; return true; } else if (c->state == 1 && pa_startswith(buf, "AT+CIND=?")) { /* we declare minimal no indicators */ - rfcomm_write(fd, "+CIND: " + rfcomm_write_response(fd, "+CIND: " /* many indicators can be supported, only call and * callheld are mandatory, so that's all we repy */ "(\"call\",(0-1))," @@ -437,11 +454,11 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf c->state = 2; return true; } else if (c->state == 2 && pa_startswith(buf, "AT+CIND?")) { - rfcomm_write(fd, "+CIND: 0,0"); + rfcomm_write_response(fd, "+CIND: 0,0"); c->state = 3; return true; } else if ((c->state == 2 || c->state == 3) && pa_startswith(buf, "AT+CMER=")) { - rfcomm_write(fd, "OK"); + rfcomm_write_response(fd, "OK"); c->state = 4; transport_put(t); return false; @@ -451,7 +468,7 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf if (c->state != 4) { pa_log_error("HFP negotiation failed in state %d with inbound %s\n", c->state, buf); - rfcomm_write(fd, "ERROR"); + rfcomm_write_response(fd, "ERROR"); return false; } @@ -516,7 +533,7 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i } if (do_reply) - rfcomm_write(fd, "OK"); + rfcomm_write_response(fd, "OK"); } return; @@ -554,9 +571,9 @@ static void set_speaker_gain(pa_bluetooth_transport *t, uint16_t gain) { * the speaker gain. In the HS role, source and sink are swapped, so * in this case we notify the AG that the microphone gain has changed */ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS || t->profile == PA_BLUETOOTH_PROFILE_HFP_HF) { - rfcomm_write(trd->rfcomm_fd, "+VGS=%d", gain); + rfcomm_write_response(trd->rfcomm_fd, "+VGS=%d", gain); } else { - rfcomm_write(trd->rfcomm_fd, "AT+VGM=%d", gain); + rfcomm_write_command(trd->rfcomm_fd, "AT+VGM=%d", gain); } } @@ -572,9 +589,9 @@ static void set_microphone_gain(pa_bluetooth_transport *t, uint16_t gain) { * the microphone gain. In the HS role, source and sink are swapped, so * in this case we notify the AG that the speaker gain has changed */ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS || t->profile == PA_BLUETOOTH_PROFILE_HFP_HF) { - rfcomm_write(trd->rfcomm_fd, "+VGM=%d", gain); + rfcomm_write_response(trd->rfcomm_fd, "+VGM=%d", gain); } else { - rfcomm_write(trd->rfcomm_fd, "AT+VGS=%d", gain); + rfcomm_write_command(trd->rfcomm_fd, "AT+VGS=%d", gain); } } -- GitLab