From patchwork Thu May 9 12:58:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajay KV X-Patchwork-Id: 795838 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 153E013C830 for ; Thu, 9 May 2024 07:32:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715239958; cv=none; b=utsqWpImqsmZEVDHvRaGgniZAlet1KyzG8nYIb7goxOjYShQiXpr318y7L/NkosfXDPKg/+vnrpPyCbGONrNCP8cOwaOEM4xGDi+tPvv/q66BpgC9mvEG5T+2lqX1INxapiBdtQHItR0+2+Z9HyqRmwWdM3t4VAjyKGsy+Kp240= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715239958; c=relaxed/simple; bh=c7NCC9QMsDwIMd2mr2vTyeQQ947gHy0DbErCBUdNe+E=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=NBODLlchVbu/xPKhABPHmiZt05dfAcmxUaYTqXUCA+XHfmnjIE+Bf0VP65rLU2o3sejGyxx5CeCWi3UgYbWGwmNA8oJ7zrjZealHcMeglEVudnpR/BdjlrYZNVERi5zI/+0T302bodQM08mqSogpKb74s68k81AodFa4N8+RG6g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=ZNJVsSeH; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="ZNJVsSeH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1715239956; x=1746775956; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=c7NCC9QMsDwIMd2mr2vTyeQQ947gHy0DbErCBUdNe+E=; b=ZNJVsSeHs7L9Na7VAL/0v5N/Iw1YaAAH1sAGzFONLgYzm8BTjezUNA8N RY/DPcbZv9qft03xkESplORJix0WHxiNalT40a2a+Pti+R431NysbSeq0 k6TMEgmHhnjBqsvZVYVo/5JM9aWKiBeoF/ajbgE0Kis2Uly2aBcqIIYf5 FWDShPbHom9uMZgCuh/xFuY9fm+aSfmxAI4hdXmdPtPeAVULUJQcNPF1r AOgLhgKhUOJlYAthEt/+zL4OUVHeUoo2h/C6zArzIepYcF12NwQ0gs2ZK gJMSIiX+SDWpxUugEST6bfnuoDk9XqYm4eA1KGWAsnOs2aqQXZ5HMxD6R g==; X-CSE-ConnectionGUID: AWT07e6wRSSDi0lMlThgAA== X-CSE-MsgGUID: fhZ8S9WYSi+jmnB4K4m7Ew== X-IronPort-AV: E=McAfee;i="6600,9927,11067"; a="14952342" X-IronPort-AV: E=Sophos;i="6.08,147,1712646000"; d="scan'208";a="14952342" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 May 2024 00:32:36 -0700 X-CSE-ConnectionGUID: P6/b3BtcStaOYA427NUzYA== X-CSE-MsgGUID: FzsLw4/SRIK/KnlcyuTfrQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,147,1712646000"; d="scan'208";a="33691067" Received: from weba0535.iind.intel.com ([10.224.186.30]) by fmviesa003.fm.intel.com with ESMTP; 09 May 2024 00:32:33 -0700 From: Ajay KV To: linux-bluetooth@vger.kernel.org Cc: Ajay KV Subject: [PATCH BlueZ v3 1/2] doc/ccpTest: Add document support for CCP test interface Date: Thu, 9 May 2024 15:58:54 +0300 Message-Id: <20240509125855.2585411-1-ajay.k.v@intel.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 call control profile interface has been documented with man page added. --- Makefile.am | 3 +- doc/org.bluez.CcpTest.5 | 82 +++++++++++++++++++++++++++++++++++++++ doc/org.bluez.CcpTest.rst | 50 ++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) 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..2c44fb52c78b 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 \ 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. From patchwork Thu May 9 12:58:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajay KV X-Patchwork-Id: 796420 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 17A8613CA81 for ; Thu, 9 May 2024 07:34:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715240076; cv=none; b=lnu2BK0oMdODmZm9co8tlelBvOe253McH78UrPogNJjSapymYq+AFVEiy337WZ7VYPB0MVSDpFUbzTs2gCMf+LkuAFh8NEuYp4gpTTE8xGVTfXzZGgr/A6PbotYwgRFhSZ7vN+b2ifePHk2irsGt9/aY+7cSwebEx5ewCDffo54= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715240076; c=relaxed/simple; bh=mLOdjEDXxcawAfcIKTW1TD6/CsHlyHU8zkn48HRyP9A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=d5sGb76soskrJIXOlgaSPt+ZsTwasVsXxQIB4LcpPJlwmKjVMxLBQ0FVkJ0LGdZ9e7MEYI86J7NqcddiKbt8AOd89z3nsw82iCXr5k7vXzhU5UgkiWzZkEPbVYht2AEnZyVdjX71omwpsfbaQY+mnUR4BC/LUx4QYBNOVTjpkwI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Gnvcucrf; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Gnvcucrf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1715240074; x=1746776074; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mLOdjEDXxcawAfcIKTW1TD6/CsHlyHU8zkn48HRyP9A=; b=Gnvcucrfqm+kMi7diJAa1wtz0KMAH3OBkNlkXb7znppaK132w8plvwAc b6TT7gssfp/iwQ6KCoT8SHObY7DTyZVaIhxWJ9v8Ec71WDn0D1+f5xSTZ GIlR7S6makh7EpJpUtZMuiSic3C7r0lC4pIMBnwGdqh4ceKTPeUCzwq3O FdysPLXero2WiGJ/RUOEOQACUmt2X+izDLkAeuA45t1SlQXD8TWzJswKe i7lWh4u0AtFuoUK6mUpZrDt/a7gcHTwtJekkNR44dKNAQixh5SyRE+6rw ybhzJtwzxarx5YIBBhpd08H7UQ+r61/kpgXBiXwekwCvDwZVeaIQLZj/7 Q==; X-CSE-ConnectionGUID: xm5ADZFJS2m2By9cmB9rIw== X-CSE-MsgGUID: 7/Zwe6W8SAeo1zGqG9WyrA== X-IronPort-AV: E=McAfee;i="6600,9927,11067"; a="14952558" X-IronPort-AV: E=Sophos;i="6.08,147,1712646000"; d="scan'208";a="14952558" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 May 2024 00:34:34 -0700 X-CSE-ConnectionGUID: jnv7r0MQQtuAYRVkXIv9Sg== X-CSE-MsgGUID: CkkhbrUsSi6NKmJinICDBg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,147,1712646000"; d="scan'208";a="33691439" Received: from weba0535.iind.intel.com ([10.224.186.30]) by fmviesa003.fm.intel.com with ESMTP; 09 May 2024 00:34:31 -0700 From: Ajay KV To: linux-bluetooth@vger.kernel.org Cc: Ajay KV Subject: [PATCH BlueZ v3 2/2] bluetoothctl: Add submenu for Call control profile testing Date: Thu, 9 May 2024 15:58:55 +0300 Message-Id: <20240509125855.2585411-2-ajay.k.v@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240509125855.2585411-1-ajay.k.v@intel.com> References: <20240509125855.2585411-1-ajay.k.v@intel.com> Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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 --- 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 +#endif + +#define _GNU_SOURCE +#include +#include +#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);