pmaports/temp/pulseaudio/0020-bluetooth-support-AT-CLCC.patch

109 lines
4.5 KiB
Diff
Raw Normal View History

From 320d906f8e64b1713dc09c8e95316c4de515f70f Mon Sep 17 00:00:00 2001
From: Dylan Van Assche <me@dylanvanassche.be>
Date: Fri, 15 Apr 2022 08:18:48 +0200
Subject: [PATCH 20/26] bluetooth: support AT+CLCC
Report ongoing calls when the HF sends an AT+CLCC command.
Currently, only one ongoing call is supported, three-way calling is not
implemented. Any additional calls are ignored.
---
src/modules/bluetooth/backend-native.c | 61 ++++++++++++++++++++++++++
src/modules/bluetooth/bluez5-util.h | 9 ++++
2 files changed, 70 insertions(+)
diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c
index fec24a57b..faefed9bd 100644
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -768,6 +768,67 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
return false;
}
pa_assert_not_reached();
+ } else if (strstr(buf, "AT+CLCC")) {
+ pa_hashmap *calls;
+ call_status_t *call;
+ unsigned int type;
+ unsigned int clcc_status;
+
+ /* Return error if ModemManager is unavailable */
+ if (!discovery->native_backend->modemmanager || !pa_modemmanager_has_modem(discovery->native_backend->modemmanager)) {
+ pa_log_debug("ModemManager backend unavailable, cannot answer AT+CLCC");
+ rfcomm_write_error(discovery->native_backend, fd, CMEE_NO_CONNECTION_TO_PHONE);
+ return false;
+ } else if (!pa_modemmanager_has_service(discovery->native_backend->modemmanager)) {
+ pa_log_debug("No network service, cannot answer AT+CLCC");
+ rfcomm_write_error(discovery->native_backend, fd, CMEE_NO_NETWORK_SERVICE);
+ return false;
+ }
+
+ calls = pa_modemmanager_get_calls(discovery->native_backend->modemmanager);
+
+ /* Check if we have any ongoing calls, if not return OK */
+ if (pa_hashmap_isempty(calls))
+ return true;
+
+ /* FIXME: support three-way calling */
+ call = pa_hashmap_first(calls);
+
+ /* Map call status to CLCC status numbers */
+ if (call->status == PA_MODEMMANAGER_CALL_STATE_INVALID) {
+ pa_log_warn("Unable to answer AT+CLCC, call state is unknown");
+ rfcomm_write_error(discovery->native_backend, fd, CMEE_AG_FAILURE);
+ return false;
+ } else if (call->is_incoming && call->status == PA_MODEMMANAGER_CALL_STATE_RINGING) {
+ clcc_status = CLCC_INCOMING;
+ } else if (!call->is_incoming && call->status == PA_MODEMMANAGER_CALL_STATE_RINGING) {
+ clcc_status = CLCC_ALERTING;
+ } else if (!call->is_incoming && call->status == PA_MODEMMANAGER_CALL_STATE_DIALING) {
+ clcc_status = CLCC_DIALING;
+ } else if (call->status == PA_MODEMMANAGER_CALL_STATE_ACTIVE) {
+ clcc_status = CLCC_ACTIVE;
+ } else if (call->status == PA_MODEMMANAGER_CALL_STATE_TERMINATED) {
+ pa_log_debug("Call terminated already, do not report it.");
+ return true;
+ /* FIXME: support three-way calling */
+ } else {
+ pa_assert_not_reached();
+ }
+
+ /* Check if call has a number, if not drop it since number and type are optional */
+ if (!call->number) {
+ rfcomm_write_response(fd, "+CLCC: %d,%d,%d,%d,%d", 1, call->is_incoming, clcc_status, 0, 0);
+ return true;
+ }
+
+ /* International numbers start with '+' */
+ if (strncmp("+", call->number, 1) == 0)
+ type = CLIP_INTERNATIONAL_NUMBER;
+ else
+ type = CLIP_NATIONAL_NUMBER;
+
+ rfcomm_write_response(fd, "+CLCC: %d,%d,%d,%d,%d,\"%s\",%d", 1, call->is_incoming, clcc_status, 0, 0, call->number, type);
+ return true;
}
/*
diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h
index 638a793b7..fb88f00e2 100644
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -233,6 +233,15 @@ typedef enum pa_bluetooth_clip {
CLIP_NATIONAL_NUMBER = 129
} pa_bluetooth_clip_t;
+/* CLCC call states, described in Bluetooth HFP 1.8 spec */
+/* FIXME: support three-way calling */
+typedef enum pa_bluetooth_clcc {
+ CLCC_ACTIVE = 0,
+ CLCC_DIALING = 2,
+ CLCC_ALERTING = 3,
+ CLCC_INCOMING = 4
+} pa_bluetooth_clcc_t;
+
#ifdef HAVE_BLUEZ_5_OFONO_HEADSET
pa_bluetooth_backend *pa_bluetooth_ofono_backend_new(pa_core *c, pa_bluetooth_discovery *y);
void pa_bluetooth_ofono_backend_free(pa_bluetooth_backend *b);
--
2.35.1