call control profile interface has been documented with
man page added.
---
Makefile.am | 6 ++-
doc/org.bluez.CcpTest.5 | 82 +++++++++++++++++++++++++++++++++++++++
doc/org.bluez.CcpTest.rst | 50 ++++++++++++++++++++++++
3 files changed, 136 insertions(+), 2 deletions(-)
create mode 100644 doc/org.bluez.CcpTest.5
create mode 100644 doc/org.bluez.CcpTest.rst
diff --git a/Makefile.am b/Makefile.am
index 05d02932f205..07019f4e1628 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -377,7 +377,8 @@ man_MANS += doc/org.bluez.obex.Client.5 doc/org.bluez.obex.Session.5 \
doc/org.bluez.obex.PhonebookAccess.5 \
doc/org.bluez.obex.MessageAccess.5 \
doc/org.bluez.obex.Message.5 \
- doc/org.bluez.obex.AgentManager.5 doc/org.bluez.obex.Agent.5
+ doc/org.bluez.obex.AgentManager.5 doc/org.bluez.obex.Agent.5 \
+ doc/org.bluez.CcpTest.5
endif
manual_pages += src/bluetoothd.8
manual_pages += doc/org.bluez.Adapter.5 doc/org.bluez.Device.5 \
@@ -465,7 +466,8 @@ EXTRA_DIST += doc/org.bluez.Adapter.rst doc/org.bluez.Device.rst \
doc/org.bluez.BatteryProviderManager.rst \
doc/org.bluez.BatteryProvider.rst doc/org.bluez.Battery.rst \
doc/org.bluez.AdminPolicySet.rst \
- doc/org.bluez.AdminPolicyStatus.rst
+ doc/org.bluez.AdminPolicyStatus.rst\
+ doc/org.bluez.CcpTest.rst
EXTRA_DIST += doc/org.bluez.Media.rst doc/org.bluez.MediaControl.rst \
doc/org.bluez.MediaPlayer.rst doc/org.bluez.MediaFolder.rst \
diff --git a/doc/org.bluez.CcpTest.5 b/doc/org.bluez.CcpTest.5
new file mode 100644
index 000000000000..b16097d08270
--- /dev/null
+++ b/doc/org.bluez.CcpTest.5
@@ -0,0 +1,82 @@
+.\" Man page generated from reStructuredText.
+.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.TH "ORG.BLUEZ.CCPTEST" 5 "May 2024" "BlueZ" "Linux System Administration"
+.SH NAME
+org.bluez.CCPTest \- BlueZ D-Bus CCPTest API documentation
+.SH INTERFACE
+.INDENT 0.0
+.TP
+.B Service
+org.bluez
+.TP
+.B Interface
+org.bluez.CCPTest1
+.TP
+.B Object path
+[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/CallerX
+.UNINDENT
+.SS Methods
+.SS void Answer()
+.INDENT 0.0
+.INDENT 3.5
+This method can be called to answer an incoming call in progress.
+.sp
+Possible errors:
+.INDENT 0.0
+.TP
+.B org.bluez.Error.Failed
+.TP
+.B org.bluez.Error.NotConnected
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.SS void Reject()
+.INDENT 0.0
+.INDENT 3.5
+This Method can be called to reject a call, which can be an active call or a call on hold state.
+.sp
+Possible errors:
+.INDENT 0.0
+.TP
+.B org.bluez.Error.Failed
+.TP
+.B org.bluez.Error.NotConnected
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.SS Properties
+.SS uint32 CallState [readonly]
+.INDENT 0.0
+.INDENT 3.5
+call index defined by CCP profile to denote the active call.
+.UNINDENT
+.UNINDENT
+.\" Generated by docutils manpage writer.
+.
diff --git a/doc/org.bluez.CcpTest.rst b/doc/org.bluez.CcpTest.rst
new file mode 100644
index 000000000000..79ead19ad538
--- /dev/null
+++ b/doc/org.bluez.CcpTest.rst
@@ -0,0 +1,50 @@
+=================
+org.bluez.CCPTest
+=================
+
+-------------------------------------
+BlueZ D-Bus CCPTest API documentation
+-------------------------------------
+
+:Version: BlueZ
+:Date: May 2024
+:Manual section: 5
+:Manual group: Linux System Administration
+
+Interface
+=========
+
+:Service: org.bluez
+:Interface: org.bluez.CCPTest1
+:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/CallerX
+
+Methods
+-------
+
+void Answer()
+``````````````
+
+ This method can be called to answer an incoming call in progress.
+
+ Possible errors:
+
+ :org.bluez.Error.Failed:
+ :org.bluez.Error.NotConnected:
+
+void Reject()
+`````````````````
+
+ This Method can be called to reject a call, which can be an active call or a call on hold state.
+
+ Possible errors:
+
+ :org.bluez.Error.Failed:
+ :org.bluez.Error.NotConnected:
+
+Properties
+----------
+
+uint32 CallState [readonly]
+```````````````````````````
+
+ call index defined by CCP profile to denote the active call.
--
2.34.1
This adds submenu in bluetoothctl for CCP Testing with
options like answer and reject the active call. This feature
is tested with windows machine as CCP server which uses Teams
application to make calls
Signed-off-by: Ajay KV <[email protected]>
---
Makefile.tools | 4 +-
client/ccp_test.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++
client/ccp_test.h | 12 +++
client/main.c | 3 +
4 files changed, 230 insertions(+), 1 deletion(-)
create mode 100644 client/ccp_test.c
create mode 100644 client/ccp_test.h
diff --git a/Makefile.tools b/Makefile.tools
index 679c914bf8cd..a5587427f549 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -13,7 +13,9 @@ client_bluetoothctl_SOURCES = client/main.c \
client/gatt.h client/gatt.c \
client/admin.h client/admin.c \
client/player.h client/player.c \
- client/mgmt.h client/mgmt.c
+ client/mgmt.h client/mgmt.c \
+ client/ccp_test.c \
+ client/ccp_test.h
client_bluetoothctl_LDADD = lib/libbluetooth-internal.la \
gdbus/libgdbus-internal.la src/libshared-glib.la \
$(GLIB_LIBS) $(DBUS_LIBS) -lreadline
diff --git a/client/ccp_test.c b/client/ccp_test.c
new file mode 100644
index 000000000000..c7d5d173f179
--- /dev/null
+++ b/client/ccp_test.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2024 Intel Corporation. All rights reserved.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include "gdbus/gdbus.h"
+#include "lib/bluetooth.h"
+#include "src/shared/shell.h"
+#include "print.h"
+#include "ccp_test.h"
+
+/* String display constants */
+#define COLORED_NEW COLOR_GREEN "NEW" COLOR_OFF
+#define COLORED_CHG COLOR_YELLOW "CHG" COLOR_OFF
+
+#define BLUEZ_CCP_TEST_INTERFACE "org.bluez.CCPTest1"
+
+static DBusConnection *dbus_conn;
+static GDBusProxy *default_call;
+static GList *callList;
+static GDBusClient *client;
+
+static char *proxy_description(GDBusProxy *proxy, const char *title,
+ const char *description)
+{
+ const char *path;
+
+ path = g_dbus_proxy_get_path(proxy);
+ return g_strdup_printf("%s%s%s%s %s ",
+ description ? "[" : "",
+ description ? : "",
+ description ? "] " : "",
+ title, path);
+}
+
+static void print_info(void *data, void *user_data)
+{
+ GDBusProxy *proxy = data;
+ const char *description = user_data;
+ char *str;
+
+ str = proxy_description(proxy, "CCP", description);
+
+ bt_shell_printf("%s%s\n", str,
+ default_call == proxy ? "[default]" : "");
+
+ g_free(str);
+}
+
+static void call_reject_reply(DBusMessage *message, void *user_data)
+{
+ DBusError error;
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, message) == TRUE) {
+ bt_shell_printf("Failed to reject call: %s\n", error.name);
+ dbus_error_free(&error);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ bt_shell_printf("operation completed\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_reject(int argc, char *argv[])
+{
+ if (!default_call) {
+ bt_shell_printf("No active calls present\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ if (g_dbus_proxy_method_call(default_call, "reject", NULL,
+ call_reject_reply, NULL, NULL) == FALSE) {
+ bt_shell_printf("Failed to reject call\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+}
+
+static void call_answer_reply(DBusMessage *message, void *user_data)
+{
+ DBusError error;
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, message) == TRUE) {
+ bt_shell_printf("Failed to answer call: %s\n", error.name);
+ dbus_error_free(&error);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ bt_shell_printf("operation completed\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_answer(int argc, char *argv[])
+{
+ if (!default_call)
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+
+ if (g_dbus_proxy_method_call(default_call, "answer", NULL,
+ call_answer_reply, NULL, NULL) == FALSE) {
+ bt_shell_printf("Failed to answer the call\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+}
+
+static const struct bt_shell_menu call_menu = {
+ .name = "ccp",
+ .desc = "ccp test settings submenu",
+ .entries = {
+ { "answer", NULL, cmd_answer, "answer the active call" },
+ { "reject", NULL, cmd_reject, "reject the active call" },
+ },
+};
+
+static void ccp_add_call(GDBusProxy *proxy)
+{
+ bt_shell_printf("[CHG] CCP Test caller added\n");
+ callList = g_list_append(callList, proxy);
+
+ if (!default_call)
+ default_call = proxy;
+
+ print_info(proxy, COLORED_NEW);
+}
+
+static void ccp_remove_call(GDBusProxy *proxy)
+{
+ bt_shell_printf("[CHG] CCP Test caller removed\n");
+
+ if (default_call == proxy)
+ default_call = NULL;
+
+ callList = g_list_remove(callList, proxy);
+}
+
+static void proxy_added(GDBusProxy *proxy, void *user_data)
+{
+ const char *interface;
+
+ interface = g_dbus_proxy_get_interface(proxy);
+
+ if (!strcmp(interface, BLUEZ_CCP_TEST_INTERFACE))
+ ccp_add_call(proxy);
+}
+
+static void proxy_removed(GDBusProxy *proxy, void *user_data)
+{
+ const char *interface;
+
+ interface = g_dbus_proxy_get_interface(proxy);
+
+ if (!strcmp(interface, BLUEZ_CCP_TEST_INTERFACE))
+ ccp_remove_call(proxy);
+}
+
+static void ccptest_property_changed(GDBusProxy *proxy, const char *name,
+ DBusMessageIter *iter)
+{
+ char *str;
+
+ str = proxy_description(proxy, "CCP Test", COLORED_CHG);
+ print_iter(str, name, iter);
+ g_free(str);
+
+ bt_shell_printf("[CHG] CCP Test property : %s\n", name);
+}
+
+static void property_changed(GDBusProxy *proxy, const char *name,
+ DBusMessageIter *iter, void *user_data)
+{
+ const char *interface;
+
+ interface = g_dbus_proxy_get_interface(proxy);
+
+ if (!strcmp(interface, BLUEZ_CCP_TEST_INTERFACE))
+ ccptest_property_changed(proxy, name, iter);
+}
+
+void ccptest_add_submenu(void)
+{
+ bt_shell_add_submenu(&call_menu);
+
+ dbus_conn = bt_shell_get_env("DBUS_CONNECTION");
+ if (!dbus_conn || client)
+ return;
+
+ client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
+
+ g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
+ property_changed, NULL);
+ g_dbus_client_set_disconnect_watch(client, NULL, NULL);
+}
+
+void ccptest_remove_submenu(void)
+{
+ g_dbus_client_unref(client);
+}
diff --git a/client/ccp_test.h b/client/ccp_test.h
new file mode 100644
index 000000000000..fc2ab2042bb8
--- /dev/null
+++ b/client/ccp_test.h
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2024 Intel Corporation. All rights reserved.
+ *
+ *
+ */
+
+void ccptest_add_submenu(void);
+void ccptest_remove_submenu(void);
diff --git a/client/main.c b/client/main.c
index c8b0f7f1c2d8..e3836d5ed3f9 100644
--- a/client/main.c
+++ b/client/main.c
@@ -34,6 +34,7 @@
#include "admin.h"
#include "player.h"
#include "mgmt.h"
+#include "ccp_test.h"
/* String display constants */
#define COLORED_NEW COLOR_GREEN "NEW" COLOR_OFF
@@ -3199,6 +3200,7 @@ int main(int argc, char *argv[])
admin_add_submenu();
player_add_submenu();
+ ccptest_add_submenu();
mgmt_add_submenu();
client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
@@ -3216,6 +3218,7 @@ int main(int argc, char *argv[])
admin_remove_submenu();
player_remove_submenu();
+ ccptest_remove_submenu();
mgmt_remove_submenu();
g_dbus_client_unref(client);
--
2.34.1
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=851987
---Test result---
Test Summary:
CheckPatch PASS 1.29 seconds
GitLint PASS 0.55 seconds
BuildEll PASS 25.41 seconds
BluezMake PASS 1769.40 seconds
MakeCheck PASS 13.25 seconds
MakeDistcheck FAIL 183.54 seconds
CheckValgrind PASS 259.91 seconds
CheckSmatch PASS 370.06 seconds
bluezmakeextell PASS 127.54 seconds
IncrementalBuild FAIL 0.06 seconds
ScanBuild FAIL 0.17 seconds
Details
##############################
Test: MakeDistcheck - FAIL
Desc: Run Bluez Make Distcheck
Output:
Package cups was not found in the pkg-config search path.
Perhaps you should add the directory containing `cups.pc'
to the PKG_CONFIG_PATH environment variable
No package 'cups' found
libtool: warning: remember to run 'libtool --finish /github/workspace/src/src/bluez-5.75/_inst/lib/bluetooth/plugins'
libtool: warning: remember to run 'libtool --finish /github/workspace/src/src/bluez-5.75/_inst/lib'
ERROR: files left in build directory after distclean:
./doc/org.bluez.CcpTest.5
make[1]: *** [Makefile:12185: distcleancheck] Error 1
make: *** [Makefile:12116: distcheck] Error 1
##############################
Test: IncrementalBuild - FAIL
Desc: Incremental build with the patches in the series
Output:
error: Your local changes to the following files would be overwritten by checkout:
doc/org.bluez.CcpTest.5
Please commit your changes or stash them before you switch branches.
Aborting
##############################
Test: ScanBuild - FAIL
Desc: Run Scan Build
Output:
Setup failed
---
Regards,
Linux Bluetooth
Hi Ajay,
On Thu, May 9, 2024 at 1:52 PM Ajay KV <[email protected]> wrote:
>
> call control profile interface has been documented with
> man page added.
> ---
> Makefile.am | 6 ++-
> doc/org.bluez.CcpTest.5 | 82 +++++++++++++++++++++++++++++++++++++++
> doc/org.bluez.CcpTest.rst | 50 ++++++++++++++++++++++++
> 3 files changed, 136 insertions(+), 2 deletions(-)
> create mode 100644 doc/org.bluez.CcpTest.5
> create mode 100644 doc/org.bluez.CcpTest.rst
>
> diff --git a/Makefile.am b/Makefile.am
> index 05d02932f205..07019f4e1628 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -377,7 +377,8 @@ man_MANS += doc/org.bluez.obex.Client.5 doc/org.bluez.obex.Session.5 \
> doc/org.bluez.obex.PhonebookAccess.5 \
> doc/org.bluez.obex.MessageAccess.5 \
> doc/org.bluez.obex.Message.5 \
> - doc/org.bluez.obex.AgentManager.5 doc/org.bluez.obex.Agent.5
> + doc/org.bluez.obex.AgentManager.5 doc/org.bluez.obex.Agent.5 \
> + doc/org.bluez.CcpTest.5
> endif
> manual_pages += src/bluetoothd.8
> manual_pages += doc/org.bluez.Adapter.5 doc/org.bluez.Device.5 \
> @@ -465,7 +466,8 @@ EXTRA_DIST += doc/org.bluez.Adapter.rst doc/org.bluez.Device.rst \
> doc/org.bluez.BatteryProviderManager.rst \
> doc/org.bluez.BatteryProvider.rst doc/org.bluez.Battery.rst \
> doc/org.bluez.AdminPolicySet.rst \
> - doc/org.bluez.AdminPolicyStatus.rst
> + doc/org.bluez.AdminPolicyStatus.rst\
> + doc/org.bluez.CcpTest.rst
>
> EXTRA_DIST += doc/org.bluez.Media.rst doc/org.bluez.MediaControl.rst \
> doc/org.bluez.MediaPlayer.rst doc/org.bluez.MediaFolder.rst \
> diff --git a/doc/org.bluez.CcpTest.5 b/doc/org.bluez.CcpTest.5
> new file mode 100644
> index 000000000000..b16097d08270
> --- /dev/null
> +++ b/doc/org.bluez.CcpTest.5
The man page itself should be generated with rst2man so no need to commit it.
> @@ -0,0 +1,82 @@
> +.\" Man page generated from reStructuredText.
> +.
> +.
> +.nr rst2man-indent-level 0
> +.
> +.de1 rstReportMargin
> +\\$1 \\n[an-margin]
> +level \\n[rst2man-indent-level]
> +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
> +-
> +\\n[rst2man-indent0]
> +\\n[rst2man-indent1]
> +\\n[rst2man-indent2]
> +..
> +.de1 INDENT
> +.\" .rstReportMargin pre:
> +. RS \\$1
> +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
> +. nr rst2man-indent-level +1
> +.\" .rstReportMargin post:
> +..
> +.de UNINDENT
> +. RE
> +.\" indent \\n[an-margin]
> +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
> +.nr rst2man-indent-level -1
> +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
> +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
> +..
> +.TH "ORG.BLUEZ.CCPTEST" 5 "May 2024" "BlueZ" "Linux System Administration"
> +.SH NAME
> +org.bluez.CCPTest \- BlueZ D-Bus CCPTest API documentation
> +.SH INTERFACE
> +.INDENT 0.0
> +.TP
> +.B Service
> +org.bluez
> +.TP
> +.B Interface
> +org.bluez.CCPTest1
> +.TP
> +.B Object path
> +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/CallerX
> +.UNINDENT
> +.SS Methods
> +.SS void Answer()
> +.INDENT 0.0
> +.INDENT 3.5
> +This method can be called to answer an incoming call in progress.
> +.sp
> +Possible errors:
> +.INDENT 0.0
> +.TP
> +.B org.bluez.Error.Failed
> +.TP
> +.B org.bluez.Error.NotConnected
> +.UNINDENT
> +.UNINDENT
> +.UNINDENT
> +.SS void Reject()
> +.INDENT 0.0
> +.INDENT 3.5
> +This Method can be called to reject a call, which can be an active call or a call on hold state.
> +.sp
> +Possible errors:
> +.INDENT 0.0
> +.TP
> +.B org.bluez.Error.Failed
> +.TP
> +.B org.bluez.Error.NotConnected
> +.UNINDENT
> +.UNINDENT
> +.UNINDENT
> +.SS Properties
> +.SS uint32 CallState [readonly]
> +.INDENT 0.0
> +.INDENT 3.5
> +call index defined by CCP profile to denote the active call.
> +.UNINDENT
> +.UNINDENT
> +.\" Generated by docutils manpage writer.
> +.
> diff --git a/doc/org.bluez.CcpTest.rst b/doc/org.bluez.CcpTest.rst
> new file mode 100644
> index 000000000000..79ead19ad538
> --- /dev/null
> +++ b/doc/org.bluez.CcpTest.rst
> @@ -0,0 +1,50 @@
> +=================
> +org.bluez.CCPTest
> +=================
> +
> +-------------------------------------
> +BlueZ D-Bus CCPTest API documentation
> +-------------------------------------
> +
> +:Version: BlueZ
> +:Date: May 2024
> +:Manual section: 5
> +:Manual group: Linux System Administration
> +
> +Interface
> +=========
> +
> +:Service: org.bluez
> +:Interface: org.bluez.CCPTest1
> +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/CallerX
I'm missing something perhaps, but it seems we need another interface
that creates the calls and something like CCPCallTest1 for actually
controlling the call. Perhaps we can following something similar to
oFono interfaces in that respect:
https://kernel.googlesource.com/pub/scm/network/ofono/ofono/+/refs/heads/master/doc/voicecallmanager-api.txt
https://kernel.googlesource.com/pub/scm/network/ofono/ofono/+/refs/heads/master/doc/voicecall-api.txt
> +Methods
> +-------
> +
> +void Answer()
> +``````````````
> +
> + This method can be called to answer an incoming call in progress.
> +
> + Possible errors:
> +
> + :org.bluez.Error.Failed:
> + :org.bluez.Error.NotConnected:
> +
> +void Reject()
> +`````````````````
> +
> + This Method can be called to reject a call, which can be an active call or a call on hold state.
> +
> + Possible errors:
> +
> + :org.bluez.Error.Failed:
> + :org.bluez.Error.NotConnected:
> +
> +Properties
> +----------
> +
> +uint32 CallState [readonly]
> +```````````````````````````
> +
> + call index defined by CCP profile to denote the active call.
> --
> 2.34.1
>
>
--
Luiz Augusto von Dentz