Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion doc/connectivity/bluetooth/shell/audio/ccp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@ The Server can be controlled locally, or by a remote device (when in a call). Fo
example a remote device may initiate a call to the server,
or the Server may initiate a call to remote device, without a client.

For all commands that take an optional :code:`index`, if the index is not supplied then it defaults
to :code:`0` which is the GTBS bearer.

.. code-block:: console

ccp_call_control_server --help
ccp_call_control_server - Bluetooth CCP Call Control Server shell commands
Subcommands:
init : Initialize CCP Call Control Server
init : Initialize CCP Call Control Server
set_bearer_name : Set bearer name [index] <name>
get_bearer_name : Get bearer name [index]


Example Usage
=============
Expand All @@ -34,6 +40,25 @@ Setup
Registered bearer[1]
uart:~$ bt connect xx:xx:xx:xx:xx:xx public

Setting and getting the bearer name
-----------------------------------

.. code-block:: console

uart:~$ ccp_call_control_server get_bearer_name
Bearer[0] name: Generic TBS
uart:~$ ccp_call_control_server set_bearer_name "New name"
Bearer[0] name: New name
uart:~$ ccp_call_control_server get_bearer_name
Bearer[0] name: New name
uart:~$ ccp_call_control_server get_bearer_name 1
Bearer[1] name: Telephone Bearer #1
uart:~$ ccp_call_control_server set_bearer_name 1 "New TBS name"
Bearer[1] name: New TBS name
uart:~$ ccp_call_control_server get_bearer_name 1
Bearer[1] name: New TBS name


Call Control Client
*******************
The Call Control Client is a role that typically resides on resource constrained devices such as
Expand Down
27 changes: 27 additions & 0 deletions include/zephyr/bluetooth/audio/ccp.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,33 @@ int bt_ccp_call_control_server_register_bearer(const struct bt_tbs_register_para
*/
int bt_ccp_call_control_server_unregister_bearer(struct bt_ccp_call_control_server_bearer *bearer);

/**
* @brief Set a new bearer provider name.
*
* @param bearer The bearer to set the name for.
* @param name The new bearer provider name.
*
* @retval 0 Success
* @retval -EINVAL @p bearer or @p name is NULL, or @p name is the empty string or @p name is larger
* than @kconfig{CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH}
* @retval -EFAULT @p bearer is not registered
*/
int bt_ccp_call_control_server_set_bearer_provider_name(
struct bt_ccp_call_control_server_bearer *bearer, const char *name);

/**
* @brief Get the bearer provider name.
*
* @param[in] bearer The bearer to get the name for.
* @param[out] name Pointer that will be updated to be the bearer provider name.
*
* @retval 0 Success
* @retval -EINVAL @p bearer or @p name is NULL
* @retval -EFAULT @p bearer is not registered
*/
int bt_ccp_call_control_server_get_bearer_provider_name(
struct bt_ccp_call_control_server_bearer *bearer, const char **name);

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

/**
Expand Down
7 changes: 7 additions & 0 deletions subsys/bluetooth/audio/Kconfig.ccp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ config BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT
help
The number of supported telephone bearers on the CCP Call Control Server

config BT_CCP_CALL_CONTROL_SERVER_PROVIDER_NAME_MAX_LENGTH
int "The maximum length of the bearer provider name excluding null terminator"
default BT_TBS_MAX_PROVIDER_NAME_LENGTH
range 1 BT_TBS_MAX_PROVIDER_NAME_LENGTH
help
Sets the maximum length of the bearer provider name.

module = BT_CCP_CALL_CONTROL_SERVER
module-str = "Call Control Profile Call Control Server"
source "subsys/logging/Kconfig.template.log_config"
Expand Down
2 changes: 1 addition & 1 deletion subsys/bluetooth/audio/Kconfig.tbs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ config BT_TBS_MAX_URI_LENGTH
config BT_TBS_MAX_PROVIDER_NAME_LENGTH
int "The maximum length of the bearer provider name"
default 30
range 0 512
range 1 512
help
Sets the maximum length of the bearer provider name.

Expand Down
69 changes: 69 additions & 0 deletions subsys/bluetooth/audio/ccp_call_control_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include <zephyr/autoconf.h>
#include <zephyr/bluetooth/audio/tbs.h>
Expand All @@ -20,6 +21,7 @@ LOG_MODULE_REGISTER(bt_ccp_call_control_server, CONFIG_BT_CCP_CALL_CONTROL_SERVE

/* A service instance can either be a GTBS or a TBS instance */
struct bt_ccp_call_control_server_bearer {
char provider_name[CONFIG_BT_CCP_CALL_CONTROL_SERVER_PROVIDER_NAME_MAX_LENGTH + 1];
uint8_t tbs_index;
bool registered;
};
Expand Down Expand Up @@ -70,6 +72,8 @@ int bt_ccp_call_control_server_register_bearer(const struct bt_tbs_register_para

free_bearer->registered = true;
free_bearer->tbs_index = (uint8_t)ret;
(void)utf8_lcpy(free_bearer->provider_name, param->provider_name,
sizeof(free_bearer->provider_name));
*bearer = free_bearer;

return 0;
Expand Down Expand Up @@ -105,3 +109,68 @@ int bt_ccp_call_control_server_unregister_bearer(struct bt_ccp_call_control_serv

return 0;
}

int bt_ccp_call_control_server_set_bearer_provider_name(
struct bt_ccp_call_control_server_bearer *bearer, const char *name)
{
size_t len;

CHECKIF(bearer == NULL) {
LOG_DBG("bearer is NULL");

return -EINVAL;
}

CHECKIF(name == NULL) {
LOG_DBG("name is NULL");

return -EINVAL;
}

if (!bearer->registered) {
LOG_DBG("Bearer %p not registered", bearer);

return -EFAULT;
}

len = strlen(name);
if (len > CONFIG_BT_CCP_CALL_CONTROL_SERVER_PROVIDER_NAME_MAX_LENGTH || len == 0) {
LOG_DBG("Invalid name length: %zu", len);

return -EINVAL;
}

if (strcmp(bearer->provider_name, name) == 0) {
return 0;
}

(void)utf8_lcpy(bearer->provider_name, name, sizeof(bearer->provider_name));

return bt_tbs_set_bearer_provider_name(bearer->tbs_index, name);
}

int bt_ccp_call_control_server_get_bearer_provider_name(
struct bt_ccp_call_control_server_bearer *bearer, const char **name)
{
CHECKIF(bearer == NULL) {
LOG_DBG("bearer is NULL");

return -EINVAL;
}

CHECKIF(name == NULL) {
LOG_DBG("name is NULL");

return -EINVAL;
}

if (!bearer->registered) {
LOG_DBG("Bearer %p not registered", bearer);

return -EFAULT;
}

*name = bearer->provider_name;

return 0;
}
81 changes: 81 additions & 0 deletions subsys/bluetooth/audio/shell/ccp_call_control_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <zephyr/bluetooth/audio/tbs.h>
#include <zephyr/bluetooth/audio/ccp.h>
#include <zephyr/shell/shell.h>
#include <zephyr/shell/shell_string_conv.h>

static struct bt_ccp_call_control_server_bearer
*bearers[CONFIG_BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT];
Expand Down Expand Up @@ -79,6 +80,81 @@ static int cmd_ccp_call_control_server_init(const struct shell *sh, size_t argc,
return 0;
}

static int validate_and_get_index(const struct shell *sh, const char *index_arg)
{
unsigned long index;
int err = 0;

index = shell_strtoul(index_arg, 0, &err);
if (err != 0) {
shell_error(sh, "Could not parse index: %d", err);

return -ENOEXEC;
}

if (index >= CONFIG_BT_TBS_BEARER_COUNT) {
shell_error(sh, "Invalid index: %lu", index);

return -ENOEXEC;
}

return (int)index;
}

static int cmd_ccp_call_control_server_set_bearer_name(const struct shell *sh, size_t argc,
char *argv[])
{
const char *name;
int index = 0;
int err = 0;

if (argc > 2) {
index = validate_and_get_index(sh, argv[1]);
if (index < 0) {
return index;
}
}

name = argv[argc - 1];

err = bt_ccp_call_control_server_set_bearer_provider_name(bearers[index], name);
if (err != 0) {
shell_error(sh, "Failed to set bearer[%d] name: %d", index, err);

return -ENOEXEC;
}

shell_print(sh, "Bearer[%d] name: %s", index, name);

return 0;
}

static int cmd_ccp_call_control_server_get_bearer_name(const struct shell *sh, size_t argc,
char *argv[])
{
const char *name;
int index = 0;
int err = 0;

if (argc > 1) {
index = validate_and_get_index(sh, argv[1]);
if (index < 0) {
return index;
}
}

err = bt_ccp_call_control_server_get_bearer_provider_name(bearers[index], &name);
if (err != 0) {
shell_error(sh, "Failed to get bearer[%d] name: %d", index, err);

return -ENOEXEC;
}

shell_print(sh, "Bearer[%d] name: %s", index, name);

return 0;
}

static int cmd_ccp_call_control_server(const struct shell *sh, size_t argc, char **argv)
{
if (argc > 1) {
Expand All @@ -93,6 +169,11 @@ static int cmd_ccp_call_control_server(const struct shell *sh, size_t argc, char
SHELL_STATIC_SUBCMD_SET_CREATE(ccp_call_control_server_cmds,
SHELL_CMD_ARG(init, NULL, "Initialize CCP Call Control Server",
cmd_ccp_call_control_server_init, 1, 0),
SHELL_CMD_ARG(set_bearer_name, NULL,
"Set bearer name [index] <name>",
cmd_ccp_call_control_server_set_bearer_name, 2, 1),
SHELL_CMD_ARG(get_bearer_name, NULL, "Get bearer name [index]",
cmd_ccp_call_control_server_get_bearer_name, 1, 1),
SHELL_SUBCMD_SET_END);

SHELL_CMD_ARG_REGISTER(ccp_call_control_server, &ccp_call_control_server_cmds,
Expand Down
4 changes: 4 additions & 0 deletions subsys/bluetooth/audio/tbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ struct tbs_flags {
/* A service instance can either be a GTBS or a TBS instance */
struct tbs_inst {
/* Attribute values */
/* TODO: The provider name should be removed from the tbs_inst and instead by stored by the
* user of TBS. This will be done once the CCP API is complete as the CCP Server will own
* all the data instead of the TBS
*/
char provider_name[CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH];
char uci[BT_TBS_MAX_UCI_SIZE];
uint8_t technology;
Expand Down
Loading