109 lines
4.5 KiB
Diff
109 lines
4.5 KiB
Diff
|
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
|
||
|
|