Move the header file csis.h from the internal location to the public include directory. This file is supposed to provide the public API for CSIS and the CSIS client, but is not fully complete yet. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
261 lines
6.2 KiB
C
261 lines
6.2 KiB
C
/**
|
|
* @file
|
|
* @brief Shell APIs for Bluetooth CSIS
|
|
*
|
|
* Copyright (c) 2020 Bose Corporation
|
|
* Copyright (c) 2021 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/types.h>
|
|
|
|
#include <zephyr.h>
|
|
#include <zephyr/types.h>
|
|
#include <shell/shell.h>
|
|
#include <stdlib.h>
|
|
#include <bluetooth/gatt.h>
|
|
#include <bluetooth/bluetooth.h>
|
|
#include <bluetooth/audio/csis.h>
|
|
#include "bt.h"
|
|
|
|
extern const struct shell *ctx_shell;
|
|
static struct bt_csis *csis;
|
|
static uint8_t sirk_read_rsp = BT_CSIS_READ_SIRK_REQ_RSP_ACCEPT;
|
|
|
|
static void locked_cb(struct bt_conn *conn, struct bt_csis *csis, bool locked)
|
|
{
|
|
if (conn == NULL) {
|
|
shell_error(ctx_shell, "Server %s the device",
|
|
locked ? "locked" : "released");
|
|
} else {
|
|
char addr[BT_ADDR_LE_STR_LEN];
|
|
|
|
conn_addr_str(conn, addr, sizeof(addr));
|
|
|
|
shell_print(ctx_shell, "Client %s %s the device",
|
|
addr, locked ? "locked" : "released");
|
|
}
|
|
}
|
|
|
|
static uint8_t sirk_read_req_cb(struct bt_conn *conn, struct bt_csis *csis)
|
|
{
|
|
char addr[BT_ADDR_LE_STR_LEN];
|
|
static const char *const rsp_strings[] = {
|
|
"Accept", "Accept Enc", "Reject", "OOB only"
|
|
};
|
|
|
|
conn_addr_str(conn, addr, sizeof(addr));
|
|
|
|
shell_print(ctx_shell, "Client %s requested to read the sirk. "
|
|
"Responding with %s", addr, rsp_strings[sirk_read_rsp]);
|
|
|
|
return sirk_read_rsp;
|
|
}
|
|
|
|
struct bt_csis_cb csis_cbs = {
|
|
.lock_changed = locked_cb,
|
|
.sirk_read_req = sirk_read_req_cb,
|
|
};
|
|
|
|
static int cmd_csis_register(const struct shell *sh, size_t argc, char **argv)
|
|
{
|
|
int err;
|
|
struct bt_csis_register_param param = {
|
|
.set_size = 2,
|
|
.rank = 1,
|
|
.lockable = true,
|
|
/* Using the CSIS test sample SIRK */
|
|
.set_sirk = { 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce,
|
|
0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 },
|
|
.cb = &csis_cbs
|
|
};
|
|
|
|
for (size_t argn = 1; argn < argc; argn++) {
|
|
const char *arg = argv[argn];
|
|
|
|
if (strcmp(arg, "size") == 0) {
|
|
param.set_size = strtol(argv[++argn], NULL, 10);
|
|
} else if (strcmp(arg, "rank") == 0) {
|
|
param.rank = strtol(argv[++argn], NULL, 10);
|
|
} else if (strcmp(arg, "not-lockable") == 0) {
|
|
param.lockable = false;
|
|
} else if (strcmp(arg, "sirk") == 0) {
|
|
size_t len;
|
|
|
|
argn++;
|
|
len = hex2bin(argv[argn], strlen(argv[argn]),
|
|
param.set_sirk, sizeof(param.set_sirk));
|
|
if (len == 0) {
|
|
shell_error(sh, "Could not parse SIRK");
|
|
return -ENOEXEC;
|
|
}
|
|
} else {
|
|
shell_help(sh);
|
|
return SHELL_CMD_HELP_PRINTED;
|
|
}
|
|
}
|
|
|
|
err = bt_csis_register(¶m, &csis);
|
|
if (err != 0) {
|
|
shell_error(sh, "Could not register CSIS: %d", err);
|
|
return err;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_csis_advertise(const struct shell *sh, size_t argc,
|
|
char *argv[])
|
|
{
|
|
int err;
|
|
|
|
if (strcmp(argv[1], "off") == 0) {
|
|
err = bt_csis_advertise(csis, false);
|
|
if (err != 0) {
|
|
shell_error(sh, "Failed to stop advertising %d", err);
|
|
return -ENOEXEC;
|
|
}
|
|
shell_print(sh, "Advertising stopped");
|
|
} else if (strcmp(argv[1], "on") == 0) {
|
|
err = bt_csis_advertise(csis, true);
|
|
if (err != 0) {
|
|
shell_error(sh, "Failed to start advertising %d", err);
|
|
return -ENOEXEC;
|
|
}
|
|
shell_print(sh, "Advertising started");
|
|
} else {
|
|
shell_error(sh, "Invalid argument: %s", argv[1]);
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_csis_update_psri(const struct shell *sh, size_t argc,
|
|
char *argv[])
|
|
{
|
|
int err;
|
|
|
|
if (bt_csis_advertise(csis, false) != 0) {
|
|
shell_error(sh,
|
|
"Failed to stop advertising - psri not updated");
|
|
return -ENOEXEC;
|
|
}
|
|
err = bt_csis_advertise(csis, true);
|
|
if (err != 0) {
|
|
shell_error(sh,
|
|
"Failed to start advertising - psri not updated");
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
shell_print(sh, "PSRI and optionally RPA updated");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_csis_print_sirk(const struct shell *sh, size_t argc,
|
|
char *argv[])
|
|
{
|
|
bt_csis_print_sirk(csis);
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_csis_lock(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
int err;
|
|
|
|
err = bt_csis_lock(csis, true, false);
|
|
if (err != 0) {
|
|
shell_error(sh, "Failed to set lock: %d", err);
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
shell_print(sh, "Set locked");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_csis_release(const struct shell *sh, size_t argc,
|
|
char *argv[])
|
|
{
|
|
bool force = false;
|
|
int err;
|
|
|
|
if (argc > 1) {
|
|
if (strcmp(argv[1], "force") == 0) {
|
|
force = true;
|
|
} else {
|
|
shell_error(sh, "Unknown parameter: %s", argv[1]);
|
|
return -ENOEXEC;
|
|
}
|
|
}
|
|
|
|
err = bt_csis_lock(csis, false, force);
|
|
|
|
if (err != 0) {
|
|
shell_error(sh, "Failed to release lock: %d", err);
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
shell_print(sh, "Set released");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_csis_set_sirk_rsp(const struct shell *sh, size_t argc,
|
|
char *argv[])
|
|
{
|
|
if (strcmp(argv[1], "accept") == 0) {
|
|
sirk_read_rsp = BT_CSIS_READ_SIRK_REQ_RSP_ACCEPT;
|
|
} else if (strcmp(argv[1], "accept_enc") == 0) {
|
|
sirk_read_rsp = BT_CSIS_READ_SIRK_REQ_RSP_ACCEPT_ENC;
|
|
} else if (strcmp(argv[1], "reject") == 0) {
|
|
sirk_read_rsp = BT_CSIS_READ_SIRK_REQ_RSP_REJECT;
|
|
} else if (strcmp(argv[1], "oob") == 0) {
|
|
sirk_read_rsp = BT_CSIS_READ_SIRK_REQ_RSP_OOB_ONLY;
|
|
} else {
|
|
shell_error(sh, "Unknown parameter: %s", argv[1]);
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_csis(const struct shell *sh, size_t argc, char **argv)
|
|
{
|
|
shell_error(sh, "%s unknown parameter: %s", argv[0], argv[1]);
|
|
|
|
return -ENOEXEC;
|
|
}
|
|
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(csis_cmds,
|
|
SHELL_CMD_ARG(register, NULL,
|
|
"Initialize the service and register callbacks "
|
|
"[size <int>] [rank <int>] [not-lockable] [sirk <data>]",
|
|
cmd_csis_register, 1, 4),
|
|
SHELL_CMD_ARG(advertise, NULL,
|
|
"Start/stop advertising CSIS PSRIs <on/off>",
|
|
cmd_csis_advertise, 2, 0),
|
|
SHELL_CMD_ARG(update_psri, NULL,
|
|
"Update the advertised PSRI",
|
|
cmd_csis_update_psri, 1, 0),
|
|
SHELL_CMD_ARG(lock, NULL,
|
|
"Lock the set",
|
|
cmd_csis_lock, 1, 0),
|
|
SHELL_CMD_ARG(release, NULL,
|
|
"Release the set [force]",
|
|
cmd_csis_release, 1, 1),
|
|
SHELL_CMD_ARG(print_sirk, NULL,
|
|
"Print the currently used SIRK",
|
|
cmd_csis_print_sirk, 1, 0),
|
|
SHELL_CMD_ARG(set_sirk_rsp, NULL,
|
|
"Set the response used in SIRK requests "
|
|
"<accept, accept_enc, reject, oob>",
|
|
cmd_csis_set_sirk_rsp, 2, 0),
|
|
SHELL_SUBCMD_SET_END
|
|
);
|
|
|
|
SHELL_CMD_ARG_REGISTER(csis, &csis_cmds, "Bluetooth CSIS shell commands",
|
|
cmd_csis, 1, 1);
|