Skip to content

Commit

Permalink
Bluetooth: CCP: Initial CCP Client implemenation
Browse files Browse the repository at this point in the history
Added initial CCP client implementation that simply
does discovery of TBS on a remote CCP server.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
  • Loading branch information
Thalley committed Jan 8, 2025
1 parent 52fd016 commit e6d1651
Show file tree
Hide file tree
Showing 44 changed files with 1,678 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,8 @@ Bluetooth Audio Stack.
| | | | | - Shell Module | - Sample Application (in progress) |
| | | | | - BSIM test | |
| +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+
| | Call Control Client | 1.0 | 3.0 | - Feature complete | - API refactor |
| | | | | - Shell Module | - Sample Application |
| | Call Control Client | 1.0 | 3.0 | - Feature complete | - API refactor (in progress) |
| | | | | - Shell Module | - Sample Application (in progress) |
| | | | | - BSIM test | |
+--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+
| MCP | Media Control Server | 1.0 | 3.0 | - Feature complete | - API refactor |
Expand Down
25 changes: 25 additions & 0 deletions doc/connectivity/bluetooth/shell/audio/ccp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,28 @@ Setup
Registered GTBS bearer
Registered bearer[1]
uart:~$ bt connect xx:xx:xx:xx:xx:xx public
Call Control Client
*******************
The Call Control Client is a role that typically resides on resource contrained devices such as
earbuds or headsets.

Using the Call Control Client
=============================
The Client can control a remote CCP server device.
For example a remote device may have an incoming call that can be accepted by the Client.

.. code-block:: console
uart:~$ ccp_call_control_client --help
ccp_call_control_client - Bluetooth CCP Call Control Client shell commands
Subcommands:
discover : Discover GTBS and TBS on remote device
Example Usage when connected
============================

.. code-block:: console
uart:~$ ccp_call_control_client discover
Discovery completed with GTBS and 1 TBS bearers
80 changes: 80 additions & 0 deletions include/zephyr/bluetooth/audio/ccp.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@
* The profile is not limited to carrier phone calls and can be used with common applications like
* Discord and Teams.
*/
#include <stdint.h>

#include <zephyr/autoconf.h>
#include <zephyr/bluetooth/audio/tbs.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/sys/slist.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -90,6 +94,82 @@ int bt_ccp_call_control_server_unregister_bearer(struct bt_ccp_call_control_serv

/** @} */ /* End of group bt_ccp_call_control_server */

/**
* @defgroup bt_ccp_call_control_client CCP Call Control Client APIs
* @ingroup bt_ccp
* @{
*/
/** Abstract Call Control Client structure. */
struct bt_ccp_call_control_client;

/** Abstract Call Control Client bearer structure. */
struct bt_ccp_call_control_client_bearer;

/** Struct with information about bearers of a client */
struct bt_ccp_call_control_client_bearers {
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
/** The GTBS bearer. */
struct bt_ccp_call_control_client_bearer *gtbs_bearer;
#endif /* CONFIG_BT_TBS_CLIENT_GTBS */

#if defined(CONFIG_BT_TBS_CLIENT_TBS)
/** Number of TBS bearers in @p tbs_bearers */
size_t tbs_count;

/** Array of pointers of TBS bearers */
struct bt_ccp_call_control_client_bearer
*tbs_bearers[CONFIG_BT_CCP_CALL_CONTROL_CLIENT_BEARER_COUNT];
#endif /* CONFIG_BT_TBS_CLIENT_TBS */
};

/**
* @brief Struct to hold the Telephone Bearer Service client callbacks
*
* These can be registered for usage with bt_tbs_client_register_cb().
*/
struct bt_ccp_call_control_client_cb {
/**
* @brief Callback function for bt_ccp_call_control_client_discover().
*
* This callback is called once the discovery procedure is completed.
*
* @param client Call Control Client pointer.
* @param err Error value. 0 on success, GATT error on positive
* value or errno on negative value.
* @param bearers The bearers found.
*/
void (*discover)(struct bt_ccp_call_control_client *client, int err,
struct bt_ccp_call_control_client_bearers *bearers);

/** @internal Internally used field for list handling */
sys_snode_t _node;
};

int bt_ccp_call_control_client_discover(struct bt_conn *conn,
struct bt_ccp_call_control_client **out_client);

/**
* @brief Register callbacks for the Call Control Client
*
* @param cb The callback struct
*
* @retval 0 Succsss
* @retval -EINVAL @p cb is NULL
* @retval -EEXISTS @p cb is already registered
*/
int bt_ccp_call_control_client_register_cb(struct bt_ccp_call_control_client_cb *cb);

/**
* @brief Unregister callbacks for the Call Control Client
*
* @param cb The callback struct
*
* @retval 0 Succsss
* @retval -EINVAL @p cb is NULL
* @retval -EALREADY @p cb is not registered
*/
int bt_ccp_call_control_client_unregister_cb(struct bt_ccp_call_control_client_cb *cb);
/** @} */ /* End of group bt_ccp_call_control_client */
#ifdef __cplusplus
}
#endif
Expand Down
11 changes: 11 additions & 0 deletions samples/bluetooth/ccp_call_control_client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(ccp_call_control_client)

target_sources(app PRIVATE
src/main.c
)

zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth)
15 changes: 15 additions & 0 deletions samples/bluetooth/ccp_call_control_client/Kconfig.sysbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

source "share/sysbuild/Kconfig"

config NET_CORE_BOARD
string
default "nrf5340dk/nrf5340/cpunet" if "$(BOARD)" = "nrf5340dk"
default "nrf5340_audio_dk/nrf5340/cpunet" if "$(BOARD)" = "nrf5340_audio_dk"
default "nrf5340bsim/nrf5340/cpunet" if $(BOARD_TARGET_STRING) = "NRF5340BSIM_NRF5340_CPUAPP"

config NET_CORE_IMAGE_HCI_IPC
bool "HCI IPC image on network core"
default y
depends on NET_CORE_BOARD != ""
78 changes: 78 additions & 0 deletions samples/bluetooth/ccp_call_control_client/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
.. zephyr:code-sample:: bluetooth_ccp_call_control_client
:name: Call Control Profile (CCP) Call Control Server
:relevant-api: bluetooth bt_ccp bt_tbs

CCP Call Control Server sample that registers one or more TBS bearers and advertises the
TBS UUID(s).

Overview
********

Application demonstrating the CCP Call Control Client functionality.
Starts by scanning for a CCP Call Control Server to connect and set up calls.

The profile works for both GAP Central and GAP Peripheral devices, but this sample only assumes the
GAP Central role.

This sample can be found under :zephyr_file:`samples/bluetooth/ccp_call_control_client`
in the Zephyr tree.

Check the :zephyr:code-sample-category:`bluetooth` samples for general information.

Requirements
************

* BlueZ running on the host, or
* A board with Bluetooth Low Energy 5.2 support

Building and Running
********************

When building targeting an nrf52 series board with the Zephyr Bluetooth Controller,
use ``-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf`` to enable the required feature support.

Building for an nrf5340dk
-------------------------

You can build both the application core image and an appropriate controller image for the network
core with:

.. zephyr-app-commands::
:zephyr-app: samples/bluetooth/ccp_call_control_client/
:board: nrf5340dk/nrf5340/cpuapp
:goals: build
:west-args: --sysbuild

If you prefer to only build the application core image, you can do so by doing instead:

.. zephyr-app-commands::
:zephyr-app: samples/bluetooth/ccp_call_control_client/
:board: nrf5340dk/nrf5340/cpuapp
:goals: build

In that case you can pair this application core image with the
:zephyr:code-sample:`bluetooth_hci_ipc` sample
:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf` configuration.

Building for a simulated nrf5340bsim
------------------------------------

Similarly to how you would for real HW, you can do:

.. zephyr-app-commands::
:zephyr-app: samples/bluetooth/ccp_call_control_client/
:board: nrf5340bsim/nrf5340/cpuapp
:goals: build
:west-args: --sysbuild

Note this will produce a Linux executable in :file:`./build/zephyr/zephyr.exe`.
For more information, check :ref:`this board documentation <nrf5340bsim>`.

Building for a simulated nrf52_bsim
-----------------------------------

.. zephyr-app-commands::
:zephyr-app: samples/bluetooth/ccp_call_control_client/
:board: nrf52_bsim
:goals: build
:gen-args: -DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CONFIG_BT_BUF_EVT_RX_SIZE=255
CONFIG_BT_BUF_ACL_RX_SIZE=255
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_CMD_TX_SIZE=255

CONFIG_BT_SEND_ECC_EMULATION=y
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CONFIG_BT_BUF_EVT_RX_SIZE=255
CONFIG_BT_BUF_ACL_RX_SIZE=255
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_CMD_TX_SIZE=255

CONFIG_BT_SEND_ECC_EMULATION=y
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Zephyr Bluetooth Controller
CONFIG_BT_LL_SW_SPLIT=y

# Zephyr Controller tested maximum advertising data that can be set in a single HCI command
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=191
CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=191
22 changes: 22 additions & 0 deletions samples/bluetooth/ccp_call_control_client/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
CONFIG_BT=y
CONFIG_LOG=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_GATT_AUTO_DISCOVER_CCC=y
CONFIG_BT_AUDIO=y
CONFIG_BT_EXT_ADV=y
CONFIG_BT_DEVICE_NAME="CCP Call Control Client"

CONFIG_BT_SMP=y
CONFIG_BT_KEYS_OVERWRITE_OLDEST=y

# CCP support
CONFIG_BT_CCP_CALL_CONTROL_CLIENT=y
CONFIG_BT_CCP_CALL_CONTROL_CLIENT_BEARER_COUNT=2
CONFIG_BT_TBS_CLIENT_GTBS=y
CONFIG_BT_TBS_CLIENT_TBS=y
CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES=1
CONFIG_UTF8=y

# TBS Client may require up to 12 buffers
CONFIG_BT_ATT_TX_COUNT=12
30 changes: 30 additions & 0 deletions samples/bluetooth/ccp_call_control_client/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
sample:
description: Bluetooth Low Energy Call Control Profile Server sample
name: Bluetooth Low Energy Call Control Profile Server sample
tests:
sample.bluetooth.ccp_call_control_client:
harness: bluetooth
platform_allow:
- qemu_cortex_m3
- qemu_x86
- nrf5340dk/nrf5340/cpuapp
- nrf5340bsim/nrf5340/cpuapp
integration_platforms:
- qemu_x86
- nrf5340dk/nrf5340/cpuapp
tags: bluetooth
sysbuild: true
sample.bluetooth.ccp_call_control_client.bt_ll_sw_split:
harness: bluetooth
platform_allow:
- nrf52_bsim
- nrf52833dk/nrf52833
- nrf52840dk/nrf52840
- nrf52840dongle/nrf52840
integration_platforms:
- nrf52_bsim
- nrf52833dk/nrf52833
- nrf52840dk/nrf52840
- nrf52840dongle/nrf52840
extra_args: OVERLAY_CONFIG=overlay-bt_ll_sw_split.conf
tags: bluetooth
Loading

0 comments on commit e6d1651

Please sign in to comment.