Skip to content

Commit e32debc

Browse files
committed
Bluetooth: CCP: Add support for set/get provider name
Add support for setting and getting the bearer provider name. For now the name will be duplicated by the TBS implementation, but will be optimizied in the future so only one copy of the name exists. Signed-off-by: Emil Gydesen <[email protected]>
1 parent d0fdd38 commit e32debc

File tree

8 files changed

+363
-3
lines changed

8 files changed

+363
-3
lines changed

doc/connectivity/bluetooth/shell/audio/ccp.rst

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,18 @@ The Server can be controlled locally, or by a remote device (when in a call). Fo
1313
example a remote device may initiate a call to the server,
1414
or the Server may initiate a call to remote device, without a client.
1515

16+
For all commands that take an optional :code:`index`, if the index is not supplied then it defaults
17+
to :code:`0` which is the GTBS bearer.
18+
1619
.. code-block:: console
1720
1821
ccp_call_control_server --help
1922
ccp_call_control_server - Bluetooth CCP Call Control Server shell commands
2023
Subcommands:
21-
init : Initialize CCP Call Control Server
24+
init : Initialize CCP Call Control Server
25+
set_bearer_name : Set bearer name [index] <name>
26+
get_bearer_name : Get bearer name [index]
27+
2228
2329
Example Usage
2430
=============
@@ -34,6 +40,25 @@ Setup
3440
Registered bearer[1]
3541
uart:~$ bt connect xx:xx:xx:xx:xx:xx public
3642
43+
Setting and getting the bearer name
44+
-----------------------------------
45+
46+
.. code-block:: console
47+
48+
uart:~$ ccp_call_control_server get_bearer_name
49+
Bearer[0] name: Generic TBS
50+
uart:~$ ccp_call_control_server set_bearer_name "New name"
51+
Bearer[0] name: New name
52+
uart:~$ ccp_call_control_server get_bearer_name
53+
Bearer[0] name: New name
54+
uart:~$ ccp_call_control_server get_bearer_name 1
55+
Bearer[1] name: Telephone Bearer #1
56+
uart:~$ ccp_call_control_server set_bearer_name 1 "New TBS name"
57+
Bearer[1] name: New TBS name
58+
uart:~$ ccp_call_control_server get_bearer_name 1
59+
Bearer[1] name: New TBS name
60+
61+
3762
Call Control Client
3863
*******************
3964
The Call Control Client is a role that typically resides on resource constrained devices such as

include/zephyr/bluetooth/audio/ccp.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,33 @@ int bt_ccp_call_control_server_register_bearer(const struct bt_tbs_register_para
9292
*/
9393
int bt_ccp_call_control_server_unregister_bearer(struct bt_ccp_call_control_server_bearer *bearer);
9494

95+
/**
96+
* @brief Set a new bearer provider name.
97+
*
98+
* @param bearer The bearer to set the name for.
99+
* @param name The new bearer provider name.
100+
*
101+
* @retval 0 Success
102+
* @retval -EINVAL @p bearer or @p name is NULL, or @p name is the empty string or @p name is larger
103+
* than @kconfig{CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH}
104+
* @retval -EFAULT @p bearer is not registered
105+
*/
106+
int bt_ccp_call_control_server_set_bearer_provider_name(
107+
struct bt_ccp_call_control_server_bearer *bearer, const char *name);
108+
109+
/**
110+
* @brief Get the bearer provider name.
111+
*
112+
* @param[in] bearer The bearer to get the name for.
113+
* @param[out] name Pointer that will be updated to be the bearer provider name.
114+
*
115+
* @retval 0 Success
116+
* @retval -EINVAL @p bearer or @p name is NULL
117+
* @retval -EFAULT @p bearer is not registered
118+
*/
119+
int bt_ccp_call_control_server_get_bearer_provider_name(
120+
struct bt_ccp_call_control_server_bearer *bearer, const char **name);
121+
95122
/** @} */ /* End of group bt_ccp_call_control_server */
96123

97124
/**

subsys/bluetooth/audio/Kconfig.ccp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ config BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT
5050
help
5151
The number of supported telephone bearers on the CCP Call Control Server
5252

53+
config BT_CCP_CALL_CONTROL_SERVER_PROVIDER_NAME_MAX_LENGTH
54+
int "The maximum length of the bearer provider name excluding null terminator"
55+
default BT_TBS_MAX_PROVIDER_NAME_LENGTH
56+
range 1 BT_TBS_MAX_PROVIDER_NAME_LENGTH
57+
help
58+
Sets the maximum length of the bearer provider name.
59+
5360
module = BT_CCP_CALL_CONTROL_SERVER
5461
module-str = "Call Control Profile Call Control Server"
5562
source "subsys/logging/Kconfig.template.log_config"

subsys/bluetooth/audio/Kconfig.tbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ config BT_TBS_MAX_URI_LENGTH
263263
config BT_TBS_MAX_PROVIDER_NAME_LENGTH
264264
int "The maximum length of the bearer provider name"
265265
default 30
266-
range 0 512
266+
range 1 512
267267
help
268268
Sets the maximum length of the bearer provider name.
269269

subsys/bluetooth/audio/ccp_call_control_server.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <errno.h>
99
#include <stddef.h>
1010
#include <stdint.h>
11+
#include <string.h>
1112

1213
#include <zephyr/autoconf.h>
1314
#include <zephyr/bluetooth/audio/tbs.h>
@@ -19,6 +20,7 @@ LOG_MODULE_REGISTER(bt_ccp_call_control_server, CONFIG_BT_CCP_CALL_CONTROL_SERVE
1920

2021
/* A service instance can either be a GTBS or a TBS instance */
2122
struct bt_ccp_call_control_server_bearer {
23+
char provider_name[CONFIG_BT_CCP_CALL_CONTROL_SERVER_PROVIDER_NAME_MAX_LENGTH + 1];
2224
uint8_t tbs_index;
2325
bool registered;
2426
};
@@ -69,6 +71,8 @@ int bt_ccp_call_control_server_register_bearer(const struct bt_tbs_register_para
6971

7072
free_bearer->registered = true;
7173
free_bearer->tbs_index = (uint8_t)ret;
74+
(void)utf8_lcpy(free_bearer->provider_name, param->provider_name,
75+
sizeof(free_bearer->provider_name));
7276
*bearer = free_bearer;
7377

7478
return 0;
@@ -104,3 +108,68 @@ int bt_ccp_call_control_server_unregister_bearer(struct bt_ccp_call_control_serv
104108

105109
return 0;
106110
}
111+
112+
int bt_ccp_call_control_server_set_bearer_provider_name(
113+
struct bt_ccp_call_control_server_bearer *bearer, const char *name)
114+
{
115+
size_t len;
116+
117+
CHECKIF(bearer == NULL) {
118+
LOG_DBG("bearer is NULL");
119+
120+
return -EINVAL;
121+
}
122+
123+
CHECKIF(name == NULL) {
124+
LOG_DBG("name is NULL");
125+
126+
return -EINVAL;
127+
}
128+
129+
if (!bearer->registered) {
130+
LOG_DBG("Bearer %p not registered", bearer);
131+
132+
return -EFAULT;
133+
}
134+
135+
len = strlen(name);
136+
if (len > CONFIG_BT_CCP_CALL_CONTROL_SERVER_PROVIDER_NAME_MAX_LENGTH || len == 0) {
137+
LOG_DBG("Invalid name length: %zu", len);
138+
139+
return -EINVAL;
140+
}
141+
142+
if (strcmp(bearer->provider_name, name) == 0) {
143+
return 0;
144+
}
145+
146+
(void)utf8_lcpy(bearer->provider_name, name, sizeof(bearer->provider_name));
147+
148+
return bt_tbs_set_bearer_provider_name(bearer->tbs_index, name);
149+
}
150+
151+
int bt_ccp_call_control_server_get_bearer_provider_name(
152+
struct bt_ccp_call_control_server_bearer *bearer, const char **name)
153+
{
154+
CHECKIF(bearer == NULL) {
155+
LOG_DBG("bearer is NULL");
156+
157+
return -EINVAL;
158+
}
159+
160+
CHECKIF(name == NULL) {
161+
LOG_DBG("name is NULL");
162+
163+
return -EINVAL;
164+
}
165+
166+
if (!bearer->registered) {
167+
LOG_DBG("Bearer %p not registered", bearer);
168+
169+
return -EFAULT;
170+
}
171+
172+
*name = bearer->provider_name;
173+
174+
return 0;
175+
}

subsys/bluetooth/audio/shell/ccp_call_control_server.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <zephyr/bluetooth/audio/tbs.h>
1616
#include <zephyr/bluetooth/audio/ccp.h>
1717
#include <zephyr/shell/shell.h>
18+
#include <zephyr/shell/shell_string_conv.h>
1819

1920
static struct bt_ccp_call_control_server_bearer
2021
*bearers[CONFIG_BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT];
@@ -79,6 +80,81 @@ static int cmd_ccp_call_control_server_init(const struct shell *sh, size_t argc,
7980
return 0;
8081
}
8182

83+
static int validate_and_get_index(const struct shell *sh, const char *index_arg)
84+
{
85+
unsigned long index;
86+
int err = 0;
87+
88+
index = shell_strtoul(index_arg, 0, &err);
89+
if (err != 0) {
90+
shell_error(sh, "Could not parse index: %d", err);
91+
92+
return -ENOEXEC;
93+
}
94+
95+
if (index >= CONFIG_BT_TBS_BEARER_COUNT) {
96+
shell_error(sh, "Invalid index: %lu", index);
97+
98+
return -ENOEXEC;
99+
}
100+
101+
return (int)index;
102+
}
103+
104+
static int cmd_ccp_call_control_server_set_bearer_name(const struct shell *sh, size_t argc,
105+
char *argv[])
106+
{
107+
unsigned long index = 0;
108+
const char *name;
109+
int err = 0;
110+
111+
if (argc > 2) {
112+
index = validate_and_get_index(sh, argv[1]);
113+
if (index < 0) {
114+
return index;
115+
}
116+
}
117+
118+
name = argv[argc - 1];
119+
120+
err = bt_ccp_call_control_server_set_bearer_provider_name(bearers[index], name);
121+
if (err != 0) {
122+
shell_error(sh, "Failed to set bearer[%lu] name: %d", index, err);
123+
124+
return -ENOEXEC;
125+
}
126+
127+
shell_print(sh, "Bearer[%lu] name: %s", index, name);
128+
129+
return 0;
130+
}
131+
132+
static int cmd_ccp_call_control_server_get_bearer_name(const struct shell *sh, size_t argc,
133+
char *argv[])
134+
{
135+
unsigned long index = 0;
136+
const char *name;
137+
int err = 0;
138+
139+
if (argc > 1) {
140+
index = validate_and_get_index(sh, argv[1]);
141+
if (index < 0) {
142+
return index;
143+
}
144+
}
145+
146+
err = bt_ccp_call_control_server_get_bearer_provider_name(bearers[index], &name);
147+
if (err != 0) {
148+
shell_error(sh, "Failed to get bearer[%lu] name: %d", index, err);
149+
150+
return -ENOEXEC;
151+
}
152+
153+
shell_print(sh, "Bearer[%lu] name: %s", index, name);
154+
155+
return 0;
156+
}
157+
82158
static int cmd_ccp_call_control_server(const struct shell *sh, size_t argc, char **argv)
83159
{
84160
if (argc > 1) {
@@ -93,6 +169,11 @@ static int cmd_ccp_call_control_server(const struct shell *sh, size_t argc, char
93169
SHELL_STATIC_SUBCMD_SET_CREATE(ccp_call_control_server_cmds,
94170
SHELL_CMD_ARG(init, NULL, "Initialize CCP Call Control Server",
95171
cmd_ccp_call_control_server_init, 1, 0),
172+
SHELL_CMD_ARG(set_bearer_name, NULL,
173+
"Set bearer name [index] <name>",
174+
cmd_ccp_call_control_server_set_bearer_name, 2, 1),
175+
SHELL_CMD_ARG(get_bearer_name, NULL, "Get bearer name [index]",
176+
cmd_ccp_call_control_server_get_bearer_name, 1, 1),
96177
SHELL_SUBCMD_SET_END);
97178

98179
SHELL_CMD_ARG_REGISTER(ccp_call_control_server, &ccp_call_control_server_cmds,

subsys/bluetooth/audio/tbs.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ struct tbs_flags {
5959
/* A service instance can either be a GTBS or a TBS instance */
6060
struct tbs_inst {
6161
/* Attribute values */
62+
/* TODO: The provider name should be removed from the tbs_inst and instead by stored by the
63+
* user of TBS. This will be done once the CCP API is complete as the CCP Server will own
64+
* all the data instead of the TBS
65+
*/
6266
char provider_name[CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH];
6367
char uci[BT_TBS_MAX_UCI_SIZE];
6468
uint8_t technology;

0 commit comments

Comments
 (0)