This removes odd `subscribe` parameter from bt_tbs_client_discover function parameters list. As the API user enables specific CONFIG_BT_TBS_CLIENT_* option, the client implementation should subscribe to the characteristic notifications so that the user receives the value updates. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
165 lines
3.6 KiB
C
165 lines
3.6 KiB
C
/** @file
|
|
* @brief Bluetooth Call Control Profile (CCP) Call Controller role.
|
|
*
|
|
* Copyright (c) 2020 Nordic Semiconductor ASA
|
|
* Copyright (c) 2022 Codecoup
|
|
* Copyright 2023 NXP
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/sys/printk.h>
|
|
#include <zephyr/sys/util.h>
|
|
#include <string.h>
|
|
|
|
#include <zephyr/bluetooth/conn.h>
|
|
#include <zephyr/bluetooth/audio/tbs.h>
|
|
|
|
#define URI_SEPARATOR ":"
|
|
#define CALLER_ID "friend"
|
|
|
|
static uint8_t new_call_index;
|
|
static char remote_uri[CONFIG_BT_TBS_MAX_URI_LENGTH];
|
|
|
|
static K_SEM_DEFINE(sem_discovery_done, 0, 1);
|
|
|
|
static struct bt_conn *default_conn;
|
|
|
|
static void discover_cb(struct bt_conn *conn, int err, uint8_t tbs_count, bool gtbs_found)
|
|
{
|
|
if (!gtbs_found) {
|
|
printk("CCP: Failed to discover GTBS\n");
|
|
return;
|
|
}
|
|
|
|
printk("CCP: Discovered GTBS\n");
|
|
|
|
if (err) {
|
|
printk("%s (err %d)\n", __func__, err);
|
|
return;
|
|
}
|
|
|
|
/* Read Bearer URI Schemes Supported List Characteristic */
|
|
bt_tbs_client_read_uri_list(conn, BT_TBS_GTBS_INDEX);
|
|
}
|
|
|
|
static void originate_call_cb(struct bt_conn *conn, int err, uint8_t inst_index, uint8_t call_index)
|
|
{
|
|
if (inst_index != BT_TBS_GTBS_INDEX) {
|
|
printk("Unexpected %s for instance %u\n", __func__, inst_index);
|
|
return;
|
|
}
|
|
|
|
if (err) {
|
|
printk("%s (err %d)\n", __func__, err);
|
|
return;
|
|
}
|
|
printk("CCP: Call originate successful\n");
|
|
new_call_index = call_index;
|
|
}
|
|
|
|
static void terminate_call_cb(struct bt_conn *conn, int err,
|
|
uint8_t inst_index, uint8_t call_index)
|
|
{
|
|
if (inst_index != BT_TBS_GTBS_INDEX) {
|
|
printk("Unexpected %s for instance %u\n", __func__, inst_index);
|
|
return;
|
|
}
|
|
|
|
if (err) {
|
|
printk("%s (err %d)\n", __func__, err);
|
|
return;
|
|
}
|
|
printk("CCP: Call with id %d terminated\n", call_index);
|
|
}
|
|
|
|
static void read_uri_schemes_string_cb(struct bt_conn *conn, int err,
|
|
uint8_t inst_index, const char *value)
|
|
{
|
|
size_t i;
|
|
|
|
if (inst_index != BT_TBS_GTBS_INDEX) {
|
|
printk("Unexpected %s for instance %u\n", __func__, inst_index);
|
|
return;
|
|
}
|
|
|
|
if (err) {
|
|
printk("%s (err %d)\n", __func__, err);
|
|
return;
|
|
}
|
|
|
|
/* Save first remote URI
|
|
*
|
|
* First search for the first comma (separator), and use that to determine the end of the
|
|
* first (or only) URI. Then use that length to copy the URI to `remote_uri` for later use.
|
|
*/
|
|
for (i = 0U; i < strlen(value); i++) {
|
|
if (value[i] == ',') {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i >= sizeof(remote_uri)) {
|
|
printk("Cannot store URI of length %zu: %s\n", i, value);
|
|
return;
|
|
}
|
|
|
|
strncpy(remote_uri, value, i);
|
|
remote_uri[i] = '\0';
|
|
|
|
printk("CCP: Discovered remote URI: %s\n", remote_uri);
|
|
k_sem_give(&sem_discovery_done);
|
|
}
|
|
|
|
struct bt_tbs_client_cb tbs_client_cb = {
|
|
.discover = discover_cb,
|
|
.uri_list = read_uri_schemes_string_cb,
|
|
.originate_call = originate_call_cb,
|
|
.terminate_call = terminate_call_cb,
|
|
};
|
|
|
|
int ccp_call_ctrl_init(struct bt_conn *conn)
|
|
{
|
|
int err;
|
|
|
|
default_conn = bt_conn_ref(conn);
|
|
bt_tbs_client_register_cb(&tbs_client_cb);
|
|
err = bt_tbs_client_discover(conn);
|
|
if (err != 0) {
|
|
return err;
|
|
}
|
|
k_sem_take(&sem_discovery_done, K_FOREVER);
|
|
|
|
return err;
|
|
}
|
|
|
|
int ccp_originate_call(void)
|
|
{
|
|
int err;
|
|
char uri[CONFIG_BT_TBS_MAX_URI_LENGTH];
|
|
|
|
strcpy(uri, remote_uri);
|
|
strcat(uri, URI_SEPARATOR);
|
|
strcat(uri, CALLER_ID);
|
|
|
|
err = bt_tbs_client_originate_call(default_conn, BT_TBS_GTBS_INDEX, uri);
|
|
if (err != BT_TBS_RESULT_CODE_SUCCESS) {
|
|
printk("TBS originate call failed: %d\n", err);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int ccp_terminate_call(void)
|
|
{
|
|
int err;
|
|
|
|
err = bt_tbs_client_terminate_call(default_conn, BT_TBS_GTBS_INDEX, new_call_index);
|
|
if (err != BT_TBS_RESULT_CODE_SUCCESS) {
|
|
printk("TBS terminate call failed: %d\n", err);
|
|
}
|
|
|
|
return err;
|
|
}
|